Как определить, что приложение 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
}

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


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, телефон определенно взломан.


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
}

Это хорошее решение, но xCon и другие подобные инструменты могут легко обойти эту проверку. Итак, я ищу лучшее решение.
— Алексей Робский

7
@ AlexeiRobsky не существует идеального решения. Всегда найдется кто-то, кто найдет способ обойти вашу защиту, это просто факт.
— Ричард Дж. Росс III

14

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

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

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


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 не совпадает с исходными файлами)
  • придерживался определенной версии (версия для джейлбрейка)

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


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.


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/"];
}

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)

-2

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


3
Этот ответ будет более интересным с исходным кодом. ИМХО: Это принесло бы вам пользу.
— Йохан Карлссон

5
-1 = не взломанные устройства также могут открывать и читать этот файл. (Проверено)
— французски

@JohanKarlsson Я предполагаю, что читатели здесь могут написать свой собственный исходный код. Если они не могут - что они здесь делают?
— gnasher729
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.