Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
213 changes: 188 additions & 25 deletions Utils/BrightSide/BrightSide.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,38 @@
//

import Foundation
import UIKit
import class UIKit.UIApplication

public final class BrightSide {

// MARK: - Public static methods

/// Method return false, if we can detect some common for jailbroken deivce files or can write to device
public static func isBright() -> Bool {
// Check 1 : check if current device is simulator
if isSimulator() {
return true

// Check 1 : Suspicious URL Schemes:
///Warning: Schemes should be added in Info.plist LSApplicationQueriesSchemes in other case check will always return false
if suspiciousURLs.contains(where: { canOpenUrl(urlString: $0) }) {
return false
}

// Check 2 : existence of files that are common for jailbroken devices
if isJailbreakDirectoriesExist() || canOpenCydia() {
// Check 3 : existence of files that are common for jailbroken devices
if isJailbreakDirectoriesExist() || isSuspiciousFilesCanBeOpened() {
return false
}

// Check 3 : 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
// Check 4 : Reading and writing in system directories (sandbox violation)
if canWriteToRestrictedPaths() {
return false
} catch {
}

// Check 4 : check if current device is simulator
if isSimulator() {
return true
}

return true

}

}
Expand All @@ -44,30 +47,190 @@ public final class BrightSide {

private extension BrightSide {

/// Method will return true, if any of the files typical for the jailbreak exists
private static func isJailbreakDirectoriesExist() -> Bool {
let jailbreakDirectories = [
/// Method will return true, if any of the files or dir, typical for the jailbreak, exists
static func isJailbreakDirectoriesExist() -> Bool {
var jailbreakPaths = suspiciousSystemFiles + suspiciousAppsDir + suspiciousSystemDir

// These files can give false positive in the simulator
if !isSimulator() {
jailbreakPaths += [
"/bin/bash",
"/usr/sbin/sshd",
"/usr/libexec/ssh-keysign",
"/bin/sh",
"/etc/ssh/sshd_config",
"/usr/libexec/sftp-server",
"/usr/bin/ssh"
]
}

return jailbreakPaths.contains { FileManager.default.fileExists(atPath: $0) }
}

/// Method will return true, if any of the files or dir, typical for the jailbreak, openable
static func isSuspiciousFilesCanBeOpened() -> Bool {
var jailbreakPaths = [
"/.installed_unc0ver",
"/.bootstrapped_electra",
"/Applications/Cydia.app",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/bin/bash",
"/usr/sbin/sshd",
"/etc/apt",
"/private/var/lib/apt/"
"/var/log/apt"
]
return jailbreakDirectories.map { FileManager.default.fileExists(atPath: $0) }.reduce(false, { $0 || $1 })

// These files can give false positive in the emulator
if !isSimulator() {
jailbreakPaths += [
"/bin/bash",
"/usr/sbin/sshd",
"/usr/bin/ssh"
]
}

return jailbreakPaths.contains { FileManager.default.isReadableFile(atPath: $0) }
}

/// Method will return true if we can open cydia package
private static func canOpenCydia() -> Bool {
guard let cydiaURL = URL(string: "cydia://package/com.example.package") else {
static func canOpenUrl(urlString: String) -> Bool {
guard let URL = URL(string: urlString) else {
return false
}
return UIApplication.shared.canOpenURL(cydiaURL)
return UIApplication.shared.canOpenURL(URL)
}

/// Method will return true if current device is simulator
private static func isSimulator() -> Bool {
static func isSimulator() -> Bool {
return isSimulatorCompile() || isSimulatorRuntime()
}

/// Check if writing to restricted paths is possible
static func canWriteToRestrictedPaths() -> Bool {
let restrictedPaths = [
"/",
"/root/",
"/private/",
"/jb/"
]

let stringToWrite = "Jailbreak Test"
for path in restrictedPaths {
let someRandomRestrictedPath = path + UUID().uuidString
do {
try stringToWrite.write(toFile: someRandomRestrictedPath,
atomically: true,
encoding: .utf8)
// If writing succeeds, the device is jailbroken
return true
} catch {
// Continue trying other paths
continue
}
}
// If no restricted paths could be written to, return false (not jailbroken)
return false
}

}

// MARK: - Suspicious directories and files

private extension BrightSide {

static var suspiciousAppsDir: [String] {
return [
"/Applications/Cydia.app",
"/Applications/blackra1n.app",
"/Applications/checkra1n.app",
"/Applications/Zeon.app",
"/Applications/FakeCarrier.app",
"/Applications/Icy.app",
"/Applications/IntelliScreen.app",
"/Applications/MxTube.app",
"/Applications/RockApp.app",
"/Applications/SBSettings.app",
"/Applications/WinterBoard.app",
"/Applications/Activator.app",
"/Applications/BytaFont.app",
"/Applications/Filza.app",
"/Applications/Sileo.app",
]
}

static var suspiciousSystemDir: [String] {
return [
"/private/var/lib/apt",
"/private/var/lib/cydia",
"/private/var/mobile/Library/SBSettings/Themes",
"/private/var/stash",
"/usr/bin/sshd",
"/etc/apt",
"/usr/libexec/cydia",
"/private/var/jb",
"/var/mobile/Library/Preferences/ABPattern", // A-Bypass
"/usr/lib/ABDYLD.dylib", // A-Bypass,
"/usr/lib/ABSubLoader.dylib", // A-Bypass
"/usr/sbin/frida-server", // frida
"/etc/apt/sources.list.d/electra.list", // electra
"/etc/apt/sources.list.d/sileo.sources", // electra
"/.bootstrapped_electra", // electra
"/usr/lib/libjailbreak.dylib", // electra
"/jb/lzma", // electra
"/.cydia_no_stash", // unc0ver
"/.installed_unc0ver", // unc0ver
"/jb/offsets.plist", // unc0ver
"/usr/share/jailbreak/injectme.plist", // unc0ver
"/etc/apt/undecimus/undecimus.list", // unc0ver
"/var/lib/dpkg/info/mobilesubstrate.md5sums", // unc0ver
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/jb/jailbreakd.plist", // unc0ver
"/jb/amfid_payload.dylib", // unc0ver
"/jb/libjailbreak.dylib", // unc0ver
]
}

static var suspiciousSystemFiles: [String] {
return [
"/Library/MobileSubstrate/DynamicLibraries/SSLKillSwitch2.plist",
"/Library/MobileSubstrate/DynamicLibraries",
"/usr/sbin/frida-server", // frida
"/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist",
"/Library/MobileSubstrate/DynamicLibraries/Veency.plist",
"/private/var/tmp/cydia.log",
"/System/Library/LaunchDaemons/com.ikey.bbot.plist",
"/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist",
"/Library/MobileSubstrate/MobileSubstrate.dylib",
"/private/var/db/crashreporter/LiveClock.plist",
"/usr/lib/libsubstitute.dylib",
"/private/var/lib/apt/periodic"
]
}

static var suspiciousURLs: [String] {
return [
"cydia://package/com.example.package",
"filza://",
"undecimus://",
"zbra://",
"sileo://"
]
}

}

// MARK: - Private Methods

private extension BrightSide {

static func isSimulatorRuntime() -> Bool {
return ProcessInfo.processInfo.environment["SIMULATOR_DEVICE_NAME"] != nil
}

static func isSimulatorCompile() -> Bool {
#if targetEnvironment(simulator)
return true
#else
return false
#endif
}

}