¿Cómo detecto que una aplicación de iOS se ejecuta en un teléfono con jailbreak?

Respuestas:

90

Depende de lo que quieras decir con jailbreak. En el caso simple, deberías poder ver si Cydia está instalado y seguirlo, algo así como

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

Para los núcleos pirateados, es un poco (mucho) más complicado.

wisequark
fuente
17
¿No sería suficiente buscar cualquier archivo / directorio fuera de su sandbox? ¿Me gusta / etc?
Rhythmic Fistman
58
Tenga en cuenta que no todos los usuarios tienen instalado Cydia: esta no es una buena comprobación, y más bien debe verificar si hay algo como / bin / bash que / all / users / will / have.
Grant Paul
2
¿Dónde almacena apt su información? ¿O podría simplemente llamar a un comando system () y averiguarlo? Quiero saber si tienen ciertas aplicaciones, y si las tienen, entonces restringir la aplicación
conradev
2
@RazorSharp En este punto, casi todos los usuarios tienen Cydia. Probablemente sea suficiente para comprobar eso ahora. Sin embargo, si desea una verificación 100% confiable, querrá usar una verificación basada en el núcleo como se muestra a continuación.
Grant Paul
1
FWIW las comprobaciones de archivos son triviales para evitar. Se puede usar mobilesubstrate para enganchar fileExistsAtPath:y hacer que regrese NOpor la ruta específica que verifica.
toasted_flakes
56

Este es un código que combina algunas respuestas que encontré para esta necesidad, y le dará una tasa de éxito mucho mayor:

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
fuente
1
@Porizm, esta es solo una combinación de algunas respuestas que encontré. Algunos de ellos no funcionaron para mí, pero funcionaron para otros ... así que con este código no corres riesgos ... Si usas esto, puedes estar 99% seguro. Con respecto al rendimiento, puede ejecutarlo solo una vez en cada ejecución y guardar la respuesta en algún lugar, no tiene que ejecutarlo cada vez ...
Yossi
3
@yossi y porizm apple aprobaron su aplicación que contiene el código anterior? por favor responda
karthikPrabhu Alagu
44
Este método debe ser una función C en línea, no Objective-C. Es demasiado fácil descubrir y omitir los métodos Objective-C, especialmente si lo llamaisJailbroken
programa
2
@Yossi, ¿esto cubre dispositivos con jailbreak usando Taig?
Lakshay
3
@Lakshay No lo sé ... Estás más que invitado a verificar y agregar aquí una respuesta :)
Yossi
54
+(BOOL)isJailbroken {
    NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
    return [[UIApplication sharedApplication] canOpenURL:url];
}

¿Comprobar la ruta del archivo /Applications/Cydia.appno está permitido en un teléfono normal? Nunca he oído que Apple detecte esto y rechace una aplicación, pero Apple es impredecible. Cydia tiene un esquema de URL cydia: // que se puede verificar legalmente con UIApplicationcanOpenURL:

Mark Johnson
fuente
1
Esta es una excelente manera de verificar, y no sale de su caja de arena. Claro, si el jailbreaker no tiene instalado Cydia, devolverá NO, pero creo que la mayoría de los Jailbreaks instalan Cydia.
Wim Haanstra
¿No se puede alterar esta cadena cuando la aplicación está descifrada?
NSRover
8
Para iOS9.0 + también necesita agregar la clave LSApplicationQueriesSchemes en plist de la aplicación. De lo contrario, canOpenURL siempre devolverá falso.
David V
1
Esto proporcionará un falso positivo si el usuario tiene instalada una aplicación que cumple con el esquema cydia: // como InstantTV.
thattyson
@thattyson gracias! Estaba buscando comprobar por qué recibía falsos positivos
rickrvo
52

Comprobar si el núcleo está roto no es TAN mucho más complicado.

El jailbreak hace que la verificación de la firma del núcleo del código firmado siempre informe que el código está firmado correctamente, los teléfonos ininterrumpidos no pueden ejecutar código con una firma incorrecta.

Por lo tanto, incluya un ejecutable separado en la aplicación con una firma incorrecta. Podría ser un programa de 3 líneas que tiene main () y un valor de retorno. Compile el ejecutable sin firmar el código (desactívelo en Configuración del proyecto-> Compilar) y fíjelo con una clave diferente utilizando la utilidad de línea de comandos "codesign".

Haga que su aplicación ejecute el ejecutable separado. Si su programa no puede obtener el valor de retorno cuando ejecuta el ejecutable separado con el signo incorrecto, definitivamente está encarcelado. Si el ejecutable separado devuelve A-OK, el teléfono está definitivamente liberado.

GregH
fuente
13
¿Puedes obtener un (sub) ejecutable cuya firma no sea válida de esa manera a través de la App Store?
fbrereto
34
¿Quizás las cosas han cambiado pero no ejecutar un ejecutable por separado no le permitiría ser aprobado para la tienda de aplicaciones?
Peter Zich
44
¿Alguien puede responder a los comentarios anteriores? Estas son preguntas importantes.
Petr
Nadie realmente va a impedir que escriba un Mach-O en el disco con una firma no válida. Sin embargo, no estoy de acuerdo con la respuesta de que verificar que el núcleo está roto no está involucrado o que esta es una verificación definitiva de ninguna manera.
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
fuente
Esa es una buena solución, pero xCon y otras herramientas como esta pueden omitir fácilmente esta verificación. Entonces, estoy buscando una mejor solución.
Alexei Robsky
77
@AlexeiRobsky no hay una solución perfecta. Siempre habrá alguien que encuentre la manera de eludir su protección, es solo un hecho.
Richard J. Ross III
14

Puede detectar si un dispositivo tiene JailBroken o no al verificar lo siguiente:

  • Cydia está instalada
  • Verifique algunas de las rutas del sistema
  • Realizar una verificación de integridad de sandbox
  • Realizar verificación de enlace simbólico
  • Verifique si crea y escribe archivos fuera de su Sandbox

Hay una biblioteca de código abierto que creé a partir de varios artículos y libros. Pruébalo en GitHub !

usuario3088680
fuente
14

Reformé en Swift 2.3 la solución provista por @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
fuente
6

El método más sofisticado que conozco es usar la objc_copyImageNames()función. Devuelve una lista de las bibliotecas cargadas actualmente y dado que la mayoría de las personas tienen MobileSubstrate en dispositivos con jailbreak y la mayoría de las herramientas de crack de iAP dependen de él, al menos aparecerán algunas bibliotecas de MobileSubstrate.

Maxthon Chan
fuente
¿Tiene algún enlace sobre el aspecto de las bibliotecas MobileSubstrate / CydiaSubstrate? No tengo un teléfono con jailbreak con el que jugar, así que conduzco "a ciegas" y las búsquedas de Google básicamente muestran tu comentario anterior.
chadbag
@chadbag Tampoco tengo uno, pero puedes buscar el debarchivo de MobileSubstrate, descomprimirlo y ponerlo en la lista negra (casi) todo .dylibestá empaquetado.
Maxthon Chan
Gracias, tengo un código resuelto y puedo agregar algunas cosas más en función de su comentario. ¡Muchas gracias!
chadbag
4

No conozco ninguna "API" que exista para esto. Si lo hubiera, entonces un producto para enmascarar jailbreak los cubriría rápidamente.

Como mucha gente señala, es un juego de gato y ratón. Y después de que ambos jugadores se vuelvan expertos, todo se reduce a quién obtiene el primer movimiento. (Persona que sostiene el dispositivo).

Encontré muchas buenas sugerencias para detectar jailbreak en el nuevo libro de Zdziarski "Hacking and Securing iOS Apps". (Personalmente, pagué más por el libro electrónico O'Reilly porque permiten copiar y pegar).

No, no estoy afiliado a los editores. Pero lo encontré un buen libro. No me gusta publicar solo los errores de los hackers para que puedan solucionarlos, así que pensé en señalar el libro.

Walt Sellers
fuente
4

Intente ejecutar código sin firmar a través de su aplicación.

Un dispositivo con jailbreak generalmente tiene las siguientes características:

  • ejecutar código sin firmar
  • tiene instalado Cydia
  • tiene archivos de jailbreak
  • acceso completo de r / w a todo el sistema de archivos
  • algunos archivos del sistema se habrán modificado (contenido, por lo que sha1 no coincide con los archivos originales)
  • pegado a la versión específica (versión jailbreakable)

Simplemente verificar la existencia de archivos para la detección de jailbreak está condenado a fallar. Estas comprobaciones son fáciles de evitar.

kurapix
fuente
3
Intentar ejecutar código sin firmar haría que su aplicación sea rechazada de la tienda de aplicaciones
Frederic Yesid Peña Sánchez
4

Algunos archivos comunes 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

La mayoría busca archivos relacionados con Cydia.

DevC
fuente
3

Sugeriría buscar archivos que no están presentes en un iPhone "normal". Todos los kits de jailbreak que he visto instalan ssh. Ese podría ser un buen indicador de un teléfono con jailbreak.

Gordon Wilson
fuente
18
ssh nunca se instala automáticamente, los usuarios deben instalarlo ellos mismos.
Grant Paul
1
Realmente no he seguido el ritmo de la escena del jailbreak. Pero, según recuerdo, cuando escribí esto (enero de 2009), Ziphone y otros instalaron ssh y el subsistema bsd de forma predeterminada. Quizás eso ya no sea cierto.
Gordon Wilson
12
confía en mí cuando digo que chpwn ha seguido el ritmo de la escena de jailbreak.
Winfield Trail
3

Lo que hicimos es que ya tenemos una fuente RSS para comunicarnos con nuestros usuarios ( Stocks Live ), ponemos una noticia que dice algo como esto:

Algunos dispositivos con jailbreak tienen problemas bla bla bla, hicimos un truco para resolver esos problemas, pero necesitamos saber si este es un dispositivo con jailbreak o no, presione aquí para que la aplicación solucione el problema. Si alguna vez vuelve a la normalidad, es decir, eliminó el jailbreak, presione aquí.

Luego, procesa la interacción del usuario y hace lo apropiado, como comportarse de manera diferente, etc.

Ilam
fuente
3

Intenta encontrar un archivo creado por Cydia o Jailbreak. O intente escribir en un archivo fuera de la caja negra de la aplicación. Si logra hacerlo, el dispositivo está comprometido / con jailbreak :)

- (BOOL)jailbroken
{
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
karim
fuente
2
¿Apple aprobó su aplicación que contiene el código anterior?
karthikPrabhu Alagu
3

Utilice el siguiente código para Swift 4 y superior: agregue el siguiente código en el 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
fuente
1

Aquí están mis soluciones: Paso 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
    }
}

Paso 2: llámelo viewDidLoad()dentro de su controlador de vista de pantalla de inicio (o cualquier VC que esté llamando por primera 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
fuente
-2

Intente acceder a /Application/Preferences.app/General.plist. Debería poder hacerlo en un iPhone con jailbreak. En un teléfono que no sea Jb, no podrá acceder a él.

aker
fuente
3
Esta respuesta sería más interesante con el código fuente. En mi humilde opinión: Esto te ganaría un voto a favor.
Johan Karlsson
55
-1 = Los dispositivos no interrumpidos también pueden abrir y leer este archivo. (Probado)
franco
@JohanKarlsson Supongo que los lectores aquí pueden escribir su propio código fuente. Si no pueden, ¿qué están haciendo aquí?
gnasher729