Як виявити, що додаток для iOS працює на розірваному телефоні?


167

Якщо я хочу, щоб мій додаток поводився по-різному на iPhone, що не має зламу, як би я вирішив це визначити?


Ви будете стежити за рухомою ціллю, але можете спробувати слідкувати за прогресом цих ресурсів, щоб побачити, наскільки ефективна ваша техніка: - theiphonewiki.com/wiki/Bypassing_Jailbreak_Detection - theiphonewiki.com/wiki/XCon
Michael Bishop

Відповіді:


90

Це залежить від того, що ви маєте на увазі під в'язницею. У простому випадку ви повинні мати змогу побачити, чи встановлена ​​Cydia та йти далі - щось подібне

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

Для зламаних ядер це трохи (набагато) більше.


17
Чи не буде достатньо шукати будь-який файл / dir поза вашою пісочницею? Як / тощо?
Ритмічний фістмен

58
Зауважте, що не у всіх користувачів встановлено Cydia - це не дуже добре, і вам слід скоріше перевірити наявність / bin / bash, що / всі / користувачі / матимуть / мати.
Грант Пол

2
Де apt зберігає свою інформацію? Або я можу просто зателефонувати команді system () і дізнатися це. Я хочу дізнатися, чи є у них певні програми, а якщо вони є, то обмежте програму
conradev

2
@RazorSharp На даний момент майже всі користувачі мають Cydia. Напевно, зараз достатньо перевірити це. Однак, якщо ви хочете на 100% надійну перевірку, ви хочете використовувати перевірку на основі ядра, як показано нижче.
Грант Пол

1
Перевірка файлів FWIW тривіальна для обходу. Можна використовувати мобільний підкладку для підключення fileExistsAtPath:і змусити його повернутися NOдля певного шляху, який ви перевіряєте.
тости_флякс

55

Це код, який поєднує в собі декілька відповідей, які я знайшов на цю потребу, і дасть вам значно вищий рівень успішності:

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%. Щодо продуктивності, ви можете запускати її лише один раз на кожному запуску і зберігати відповідь кудись. Не потрібно її виконувати кожного разу ..
Yossi

3
@yossi та porizm apple затвердили вашу програму, яка містить наведений вище код? будь ласка, відповідайте
karthikPrabhu Alagu

4
Цей метод повинен бути вбудованою функцією C, а не Objective-C. Виявити та обійти методи Objective-C надто просто, особливо якщо ви це називаєтеisJailbroken
progrmr

2
@Yossi, чи охоплює це пристрій втечу з ув'язнення за допомогою Taig?
Лакшай

3
@Lakshay Я не знаю .. Вас більше, ніж запрошено перевірити і додати тут відповідь :)
Yossi

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 завжди поверне помилковий.
Давид V

1
Це забезпечить хибнопозитивний результат, якщо у користувача встановлено додаток, який відповідає схемі cydia: // на зразок InstantTV.
thattyson

@thattyson дякую! Я шукав, щоб перевірити, чому я отримую помилкові позитиви
rickrvo

52

Перевірка, чи не зламано ядро, НЕ ЧОГО більше задіяне.

Jailbreaking змушує перевірку підпису ядра підписаного коду завжди повідомляти, що код підписаний правильно, нерозривні телефони не можуть запускати код із поганою підписом.

Отже, включіть у програму окремий виконуваний файл із неправильним підписом. Це може бути просто 3-рядова програма, яка має main () і повернене значення. Скомпілюйте виконуваний файл без підписання коду (вимкніть його в Налаштуваннях проекту-> Збірка) та підпишіть його іншим ключем за допомогою утиліти командного рядка «codeign».

Запропонуйте вашій програмі виконати окремий виконуваний файл. Якщо ваша програма не може отримати повернене значення під час запуску окремого виконуваного файлу з неправильним знаком, воно, безумовно, знаходиться у в'язниці. Якщо окремий виконуваний файл поверне A-OK, телефон, безумовно, знаходиться в безвідмовному режимі.


13
Чи можете ви отримати (під-) виконуваний файл, чий підпис недійсний через App Store?
fbrereto

34
Можливо, все змінилося, але чи не виконання окремого виконуваного файлу не дозволить вам бути схваленим у магазині додатків?
Петро Зіч

4
Чи може хтось відповісти на попередні коментарі? Це важливі питання.
Петро

Ніхто насправді не зупинить вас від написання Mach-O на диск з недійсним підписом. Однак я не згоден з відповіддю, що перевірка того, що ядро ​​зламано, не пов'язане або це остаточна перевірка будь-якими способами.
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
}

Це хороше рішення, але xCon та інші подібні інструменти можуть легко обійти цю перевірку. Отже, я шукаю кращого рішення.
Олексій Робський

7
@AlexeiRobsky немає ідеального рішення. Завжди знайдеться хтось, хто знайде спосіб обійти ваш захист, це просто факт.
Річард Дж. Росс III

14

Ви можете визначити, чи є пристрій JailBroken чи ні, перевіривши наступне:

  • Cydia встановлена
  • Перевірте деякі системні шляхи
  • Проведіть перевірку цілісності пісочниці
  • Проведіть перевірку символьного посилання
  • Перевірте, чи ви створюєте та записуєте файли за межами свого Sandbox

Є бібліотека з відкритим кодом, яку я створив з різних статей та книг. Спробуйте це на 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 на пристроях з розширеним змістом, і від цього залежить більшість інструментів тріщини, принаймні деякі бібліотеки MobileSubstrate з'являться.


Чи є у вас посилання на те, як виглядають бібліотеки MobileSubstrate / CydiaSubstrate? У мене немає розбитого телефону, з яким я можу обійтися, тому я веду «сліпо», а пошук Google, в основному, придумує ваш коментар вище.
чадбаг

@chadbag У мене немає жодного, але ви можете шукати debфайл MobileSubstrate, розпаковувати його та чорний список (майже) все .dylibце запаковано.
Макшон Чан

Дякую, я розібрався з кодом, і я можу додати ще деякі речі на основі вашого коментаря. Велике дякую!
чадбаг

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 не відставав від місця в'язниці.
Winfield Trail

3

Що ми зробили, це те, що у нас вже є RSS-канал для спілкування з нашими користувачами ( Запаси в прямому ефірі ), ми розміщуємо новину, де йдеться про щось подібне:

Деякі пристрої з джейлбрейками мають проблеми з бла-бла-бла, ми зробили хак для вирішення цих проблем, але нам потрібно знати, чи це пристрій з джейлбрейком чи ні, натисніть тут, щоб програма усунула цю проблему. Якщо ви коли-небудь повернетесь до нормального стану, тобто зняли втечу з в'язниці, натисніть тут.

Тоді ви обробляєте взаємодію з користувачем і робите все, що підходить, наприклад, поводяться різні тощо.


3

Спробуйте знайти файл, який створюють пристрої cydia або jailbroken. Або спробуйте написати у файлі, який знаходиться за межами програми blackbox. Якщо вам це вдасться, пристрій зламано / збито з розбиття :)

- (BOOL)jailbroken
{
    NSFileManager * fileManager = [NSFileManager defaultManager];
    return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}

2
Apple схвалила вашу програму, яка містить вказаний вище код?
karthikPrabhu Alagu

3

Будь ласка, використовуйте наступний код для Swift 4 і вище: Додайте такий код у додаток:

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 (_ додаток: 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()всередину контролера перегляду екрана запуску (або будь-якого VC, який ви телефонуєте вперше):

       // 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 = Unjailbroken пристрої також можуть відкривати та читати цей файл. (Випробувано)
франкіз

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