iOSアプリがジェイルブレイクした携帯電話で実行されていることを検出するにはどうすればよいですか?
質問
ジェイルブレイクされたiPhoneでアプリの動作を変えたい場合、これをどのように判断しますか?
解決
脱獄の意味に依存します。単純なケースでは、Cydiaがインストールされているかどうかを確認し、それを確認する必要があります-
NSString *filePath = @"/Applications/Cydia.app";
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath])
{
// do something useful
}
ハッキングされたカーネルの場合、少し(多く)より複雑です。
他のヒント
+(BOOL)isJailbroken {
NSURL* url = [NSURL URLWithString:@"cydia://package/com.example.package"];
return [[UIApplication sharedApplication] canOpenURL:url];
}
ファイルパス /Applications/Cydia.app
の確認は、通常の電話では許可されていませんか? Appleがこれを検出してアプリを拒否することを聞いたことはありませんが、Appleは予測不可能です。 Cydiaには URLスキームcydia:// があり、UIApplication canOpenURL:
これは、このニーズに対して私が見つけたいくつかの答えを組み合わせたコードであり、はるかに高い成功率を提供します:
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;
}
カーネルが壊れているかどうかを確認することは、それほど複雑ではありません。
ジェイルブレイクは、カーネルの署名済みコードの署名チェックで常にコードが正しく署名されていることを報告し、壊れていない電話機は不正な署名でコードを実行できません。
そのため、アプリに署名が正しくない別の実行可能ファイルを含めます。 main()と戻り値を持つ3行のプログラムだけにすることもできます。コード署名なしで実行可能ファイルをコンパイルし(プロジェクト設定->ビルドでオフにします)、" codesign"を使用して別のキーで署名します。コマンドラインユーティリティ。
アプリに別の実行可能ファイルを実行させます。悪いsigで別の実行可能ファイルを実行しているときにプログラムが戻り値を取得できない場合、それは間違いなく投獄されています。個別の実行可能ファイルがA-OKを返す場合、電話は間違いなくジェイルブレイクされています。
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
}
デバイスがJailBrokenであるかどうかを検出するには、次を確認します。
- Cydiaがインストールされています
- システムパスの一部を確認する
- サンドボックスの整合性チェックを実行する
- シンボリックリンクの検証を実行
- Sandboxの外部でファイルを作成して書き込むかどうかを確認します
さまざまな記事や書籍から作成したオープンソースライブラリがあります。 GitHubで試してみてください!
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
}
私が知っている最も洗練された方法は、 objc_copyImageNames()
関数を使用することです。現在ロードされているライブラリのリストを返します。ほとんどの人がジェイルブレイクされたデバイスにMobileSubstrateを持ち、ほとんどのiAPクラックツールがそれに依存しているため、少なくとも一部のMobileSubstrateライブラリが表示されます。
「API」は認識していませんこのために存在します。あった場合、脱獄マスキング製品はすぐにそれらをカバーします。
多くの人が指摘しているように、これは猫とマウスのゲームです。そして、両方のプレイヤーがエキスパートになった後は、誰が最初の動きを手に入れるかにかかっています。 (デバイスを持っている人。)
Zdziarskiの新しい本「iOSアプリのハッキングと保護」で脱獄を検出するための多くの良い提案を見つけました。 (個人的には、O'Reillyの電子書籍ではコピーアンドペーストが許可されているため、より多くの支払いをしました。)
いいえ、私は出版社と提携していません。しかし、私はそれを良い本だと感じました。ハッカーの間違いを修正するためにハッカーの間違いを公開するのは好きではないので、私はこの本を指すと思いました。
アプリケーションから署名のないコードを実行してみてください。
ジェイルブレイクされたデバイスには通常、次の特性があります。
- 未署名のコードを実行
- Cydiaがインストールされています
- ジェイルブレイクファイルがあります
- ファイルシステム全体への完全なr / wアクセス
- 一部のシステムファイルが変更されます(コンテンツおよびsha1は元のファイルと一致しません)
- 特定のバージョン(ジェイルブレイク可能なバージョン)にスタックする
ジェイルブレイク検出のためにファイルの存在を確認するだけでは失敗する運命にあります。 これらのチェックは簡単にバイパスできます。
確認する一般的なファイル:
/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関連ファイルのほとんどのチェック。
「バニラ」に存在しないファイルを探すことをお勧めします。 iPhone。私が見たすべての脱獄キットはsshをインストールします。これは、ジェイルブレイクした電話の良い指標かもしれません。
私たちがしたことは、ユーザーと通信するためのRSSフィードがすでにあることです( Stocks Live )、次のようなニュースアイテムを追加します。
一部のジェイルブレイクされたデバイスには問題があります。それらの問題を解決するためにハックを行いましたが、これがジェイルブレイクされたデバイスであるかどうかを知る必要があります。ジェイルブレイクを削除した場合、つまり通常の状態に戻った場合は、ここをクリックしてください。
次に、ユーザーインタラクションを処理し、異なる動作などの適切な処理を行います...
cydiaまたはジェイルブレイクされたデバイスが作成するファイルを見つけてみてください。または、アプリのブラックボックス外のファイルに書き込もうとします。成功した場合、デバイスは危険にさらされている/ジェイルブレイクされています:)
- (BOOL)jailbroken
{
NSFileManager * fileManager = [NSFileManager defaultManager];
return [fileManager fileExistsAtPath:@"/private/var/lib/apt/"];
}
移動するターゲットを追跡しますが、これらのリソースの進捗状況を追跡して、テクニックの効果を確認してください。
ここに私のソリューション:
extension UIDevice {
func isJailBroken() -> Bool {
var jailBroken = false
let cydiaPath = "/Applications/Cydia.app"
let aptPath = "/private/var/lib/apt/"
if FileManager.default.fileExists(atPath: cydiaPath) {
jailBroken = true
}
if FileManager.default.fileExists(atPath: aptPath) {
jailBroken = true
}
return jailBroken
}
}
そして、起動画面View Controller内の viewDidLoad()
内で呼び出します(またはあなたが最初に呼び出しているVC):
if UIDevice.current.isJailBroken() {
// show a blank screen or some other view controller
let jailbreakVC = JailBrokenViewController()
self.navigationController?.present(jailbreakVC, animated: true, completion:nil)
} else {
// continue executing your next View controller
let nextVC = NextViewController()
self.navigationController?.present(nextVC, animated: true, completion:nil)
}
/Application/Preferences.app/General.plistにアクセスしてみてください ジェイルブレイクしたiPhoneでできるようになるはずです 非Jb電話ではアクセスできません