Как определить, что приложение iOS работает на взломанном телефоне?

167

Если я хочу, чтобы мое приложение по-разному работало на взломанном iPhone, как бы я это определил?

Бен Готлиб
источник
Вы будете следовать за движущейся целью, но вы можете попробовать следить за ходом этих ресурсов, чтобы увидеть, насколько эффективна ваша техника: - theiphonewiki.com/wiki/Bypassing_Jailbreak_Detection - theiphonewiki.com/wiki/XCon
Майкл Бишоп

Ответы:

90

Это зависит от того, что вы подразумеваете под побег из тюрьмы. В простом случае вы сможете увидеть, установлен ли Cydia, и пойти по этому пути - что-то вроде

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

Для взломанных ядер это немного (намного) более сложно.

wisequark
источник
17
Разве этого не достаточно, чтобы найти какой-либо файл / каталог за пределами вашей песочницы? Нравится / etc?
Ритмичный кулак
58
Обратите внимание, что не у всех пользователей установлен Cydia - это не очень хорошая проверка, и вам лучше проверить что-то вроде / bin / bash, которое / all / users / will / have.
Грант Пол
2
Где apt хранит информацию? Или я могу просто вызвать команду system () и выяснить это. Я хочу выяснить, есть ли у них определенные приложения и, если они есть, ограничить приложение
conradev
2
@RazorSharp На данный момент, почти все пользователи имеют Cydia. Вероятно, достаточно проверить это сейчас. Однако, если вы хотите 100% надежную проверку, вы должны использовать проверку на основе ядра, как показано ниже.
Грант Пол
1
FWIW проверки файлов тривиально обойти. Можно использовать mobilesubstrate, чтобы подключить fileExistsAtPath:и вернуть его NOдля определенного пути, который вы проверяете.
toasted_flakes
56

Это код, который объединяет некоторые ответы, которые я нашел для этой потребности, и даст вам гораздо более высокий уровень успеха:

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;
}
Йосси
источник
1
@Porizm, это всего лишь сочетание некоторых ответов, которые я нашел. Некоторые из них не работают для меня, но работают для других ... поэтому с этим кодом вы не рискуете. Если вы используете это, вы можете быть уверены на 99%. Что касается производительности, вы можете запустить его только один раз при каждом запуске и сохранить где-нибудь ответ. Вам не нужно запускать его каждый раз ..
Йосси
3
@yossi и porizm apple одобрили ваше приложение, которое содержит приведенный выше код? пожалуйста, ответьте
karthikPrabhu Alagu
4
Этот метод должен быть встроенной функцией C, а не Objective-C. Слишком легко обнаружить и обойти методы Objective-C, особенно если вы их вызываетеisJailbroken
progrmr
2
@Yossi это покрытие устройств, взломанных с помощью Taig?
Лакшай
3
@Lakshay, я не знаю .. Вы более чем приглашены проверить и добавить сюда ответ :)
Йосси
54
+(BOOL)isJailbroken {
    NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
    return [[UIApplication sharedApplication] canOpenURL:url];
}

Проверка пути к файлу /Applications/Cydia.appне разрешена на обычном телефоне? Я никогда не слышал, чтобы Apple обнаружила это и отвергла приложение для него, но Apple непредсказуема. Cydia имеет схему URL cydia: //, которая может быть юридически проверена с помощью UIApplicationcanOpenURL:

Марк Джонсон
источник
1
Это отличный способ проверить, и он не выходит за пределы вашей песочницы. Конечно, если на джейлбрейкере не установлена ​​Cydia, он вернет НЕТ, но я думаю, что большинство джейлбрейков устанавливают Cydia.
Вим Хаанстра
нельзя ли изменить эту строку при взломе приложения?
NSRover
8
Для iOS9.0 + вам также необходимо добавить ключ LSApplicationQueriesSchemes в список приложений. В противном случае canOpenURL всегда будет возвращать false.
Давид V
1
Это даст ложное срабатывание, если у пользователя установлено приложение, соответствующее схеме cydia: //, такой как InstantTV.
thattyson
@thattyson спасибо! Я искал, чтобы проверить, почему я получаю ложные срабатывания
rickrvo
52

Проверка, не сломано ли ядро, не намного сложнее.

Jailbreaking заставляет ядро ​​проверять подпись подписанного кода всегда, сообщая, что код подписан правильно, не сломанные телефоны не могут выполнять код с плохой подписью.

Итак, включите в приложение отдельный исполняемый файл с неверной подписью. Это может быть просто трехстрочная программа, которая имеет main () и возвращаемое значение. Скомпилируйте исполняемый файл без подписи кода (отключите его в Project Settings-> Build) и подпишите его другим ключом с помощью утилиты командной строки "codesign".

Сделайте так, чтобы ваше приложение исполняло отдельный исполняемый файл. Если ваша программа не может получить возвращаемое значение при запуске отдельного исполняемого файла с плохим сигналом, она определенно заключена в тюрьму. Если отдельный исполняемый файл возвращает A-OK, телефон определенно взломан.

GregH
источник
13
Можете ли вы получить (под) исполняемый файл, чья подпись недействительна через App Store?
fbrereto
34
Возможно, все изменилось, но выполнение отдельного исполняемого файла не помешает вам быть утвержденным в магазине приложений?
Петр Зич
4
Может кто-нибудь ответить на предыдущие комментарии? Это важные вопросы.
Петр
Никто на самом деле не помешает вам записать Mach-O на диск с неверной подписью. Тем не менее, я не согласен с ответом, что проверка того, что ядро ​​сломано, не задействована или что это определенная проверка любым способом.
Саагарджа
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
}
Ричард Дж. Росс III
источник
Это хорошее решение, но xCon и другие подобные инструменты могут легко обойти эту проверку. Итак, я ищу лучшее решение.
Алексей Робский
7
@ AlexeiRobsky не существует идеального решения. Всегда найдется кто-то, кто найдет способ обойти вашу защиту, это просто факт.
Ричард Дж. Росс III
14

Вы можете определить, является ли устройство JailBroken или нет, проверив следующее:

  • Cydia установлена
  • Проверьте некоторые из системных путей
  • Выполнить проверку целостности песочницы
  • Выполнить проверку символической ссылки
  • Убедитесь, что вы создаете и пишете файлы за пределами своей песочницы

Существует библиотека с открытым исходным кодом, которую я создал из различных статей и книг. Попробуйте это на GitHub !

user3088680
источник
14

Я переработал в Swift 2.3 решение, предоставленное @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
}
Алекс Педа
источник
6

Самый сложный метод, который я знаю, это использование objc_copyImageNames()функций. Он возвращает список загруженных в настоящее время библиотек, и, поскольку большинство людей имеют MobileSubstrate на взломанных устройствах, и большинство инструментов взлома iAP зависят от него, по крайней мере, некоторые библиотеки MobileSubstrate будут отображаться.

Макстон Чан
источник
У вас есть ссылки на то, как выглядят библиотеки MobileSubstrate / CydiaSubstrate? У меня нет джейлбрейкнутого телефона, с которым можно поиграться, поэтому я езжу "вслепую", и поиски в Google в основном приводят ваш комментарий выше.
Чедбаг
@chadbag У меня его тоже нет, но вы можете найти debфайл MobileSubstrate, распаковать его и занести в черный список (почти) все .dylibупакованное.
Maxthon Chan
Спасибо, я разобрался с кодом и могу добавить еще кое-что на основе вашего комментария. Большое спасибо!
Чэдбэг
4

Мне не известны какие-либо «API», которые существуют для этого. Если бы они были, то продукт для джейлбрейк-маскировки быстро бы их прикрыл.

Как отмечают многие, это игра в кошки-мышки. И после того, как оба игрока становятся экспертами, все зависит от того, кто получит первый ход. (Человек, держащий устройство.)

Я нашел много хороших предложений по обнаружению джейлбрейка в новой книге Здзиарски «Взлом и защита приложений iOS». (Лично я заплатил больше за электронную книгу O'Reilly, потому что они позволяют копировать и вставлять.)

Нет, я не связан с издателями. Но я нашел хорошую книгу. Я не люблю просто публиковать ошибки хакеров, чтобы они могли их исправить, поэтому я решил указать на книгу.

Уолт Селлерс
источник
4

Попробуйте выполнить неподписанный код через ваше приложение.

Взломанные устройства обычно имеют следующие характеристики:

  • запустить неподписанный код
  • Cydia установлен
  • имеет джейлбрейк файлы
  • полный доступ к всей файловой системе
  • некоторые системные файлы будут изменены (содержимое и поэтому sha1 не совпадает с исходными файлами)
  • придерживался определенной версии (версия для джейлбрейка)

Просто проверка существования файла для обнаружения джейлбрейка обречена на провал. Эти проверки легко обойти.

kurapix
источник
3
Попытка выполнить неподписанный код приведет к отклонению вашего приложения из магазина приложений
Фредерик Йесид Пенья Санчес
4

Некоторые общие файлы для проверки: /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

Большинство проверяет наличие файлов, связанных с Cydia.

DevC
источник
3

Я бы посоветовал искать файлы, которых нет на «ванильном» iPhone. Все комплекты джейлбрейка, которые я видел, устанавливают ssh. Это может быть хорошим показателем взломанного телефона.

Гордон Уилсон
источник
18
ssh никогда не устанавливается автоматически, пользователи должны установить его самостоятельно.
Грант Пол
1
Я на самом деле не поспевал за сценой джейлбрейка. Но, насколько я помню, когда я писал это (январь '09), Ziphone и другие по умолчанию установили ssh и подсистему bsd. Возможно, это больше не правда.
Гордон Уилсон
12
поверь мне, когда я скажу, что chpwn идет в ногу со сценой джейлбрейка.
Уинфилд Трейл
3

То, что мы сделали, у нас уже есть RSS-канал для общения с нашими пользователями ( Stocks Live ), мы разместили новость, в которой говорится что-то вроде этого:

Некоторые взломанные устройства имеют проблемы, бла-бла-бла, мы взломали, чтобы решить эти проблемы, но нам нужно знать, является ли это взломанным устройством или нет, нажмите здесь, чтобы приложение исправило проблему. Если вы когда-нибудь вернетесь в нормальное состояние, т.е. удалили джейлбрейк, нажмите здесь.

Затем вы обрабатываете взаимодействие с пользователем и делаете то, что нужно, например, ведете себя по-другому и т. Д.

Илама
источник
3

Попробуйте найти файл, созданный cydia или взломанным устройством. Или попробуйте записать файл вне черного ящика приложения. Если вам это удастся, устройство взломано / взломано :)

- (BOOL)jailbroken
{
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
Karim
источник
2
Apple одобрила ваше приложение, содержащее приведенный выше код?
КартикПрабху Алагу
3

Пожалуйста, используйте следующий код для Swift 4 и выше: Добавьте следующий код в 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()
            }
        }
    }
}
Паритош Павар
источник
1

Вот мои решения: Шаг 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
    }
}

Шаг 2: вызовите его внутри viewDidLoad()вашего контроллера экрана запуска (или любого другого виртуального канала, который вы вызываете в первый раз):

       // 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
источник
-2

Попытайтесь получить доступ к /Application/Preferences.app/General.plist Вы должны быть в состоянии сделать это на взломанном iPhone. На телефоне без Jb вы не сможете получить к нему доступ.

Aker
источник
3
Этот ответ будет более интересным с исходным кодом. ИМХО: Это принесло бы вам пользу.
Йохан Карлссон
5
-1 = не взломанные устройства также могут открывать и читать этот файл. (Проверено)
французски
@JohanKarlsson Я предполагаю, что читатели здесь могут написать свой собственный исходный код. Если они не могут - что они здесь делают?
gnasher729