# IOSSecuritySuite **Repository Path**: wei-echo/IOSSecuritySuite ## Basic Information - **Project Name**: IOSSecuritySuite - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-07-28 - **Last Updated**: 2025-07-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## ⭐️ Do you want to become a certified iOS Application Security Engineer? ⭐️ Check out our practical & fully online course at: [https://courses.securing.pl/courses/iase](https://courses.securing.pl/courses/iase?utm_source=githubiosss&utm_medium=githubiosss&utm_campaign=githubiosss&utm_id=githubiosss) ![iASE logo](./iase_bg.png) ## ISS Description ![ISS logo](./logo.png) ### by [@_r3ggi](https://twitter.com/_r3ggi) 🌏 iOS Security Suite is an advanced and easy-to-use platform security & anti-tampering library written in pure Swift! If you are developing for iOS and you want to protect your app according to the OWASP [MASVS](https://github.com/OWASP/owasp-masvs) standard, chapter v8, then this library could save you a lot of time. πŸš€ What ISS detects: * Jailbreak (even the iOS 11+ with brand new indicators! πŸ”₯) * Attached debugger πŸ‘¨πŸ»β€πŸš€ * If an app was run in an emulator πŸ‘½ * Common reverse engineering tools running on the device πŸ”­ ## Setup There are 4 ways you can start using IOSSecuritySuite ### 1. Add source Add `IOSSecuritySuite/*.swift` files to your project ### 2. Setup with CocoaPods `pod 'IOSSecuritySuite'` ### 3. Setup with Carthage `github "securing/IOSSecuritySuite"` ### 4. Setup with Swift Package Manager ```swift .package(url: "https://github.com/securing/IOSSecuritySuite.git", from: "1.5.0") ``` ### Update Info.plist After adding ISS to your project, you will also need to update your main Info.plist. There is a check in jailbreak detection module that uses ```canOpenURL(_:)``` method and [requires](https://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl) specifying URLs that will be queried. ```xml LSApplicationQueriesSchemes undecimus sileo zbra filza ``` ### Pricing Check our EULA license for the details. TLDR: If your company employs: * 0-99 people - **free to use** * 100-1000 - 3k EUR/year * 1000+ - 10k EUR/year If you want to sell a module that uses the iOS Security Suite (it is not used directly in your app) - 10k EUR/year ### Notice iOS Security Suite is meant to be used on iOS/iPadOS. It should not be used on Macs with Apple Silicon. ## How to use ### Jailbreak detector module * **The simplest method** returns True/False if you just want to know if the device is jailbroken or jailed ```Swift if IOSSecuritySuite.amIJailbroken() { print("This device is jailbroken") } else { print("This device is not jailbroken") } ``` * **Verbose**, if you also want to know what indicators were identified ```Swift let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailMessage() if jailbreakStatus.jailbroken { print("This device is jailbroken") print("Because: \(jailbreakStatus.failMessage)") } else { print("This device is not jailbroken") } ``` The failMessage is a String containing comma-separated indicators as shown on the example below: `sileo:// URL scheme detected, Suspicious file exists: /Library/MobileSubstrate/MobileSubstrate.dylib, Fork was able to create a new process` * **Verbose & filterable**, if you also want to for example identify devices that were jailbroken in the past, but now are jailed ```Swift let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailedChecks() if jailbreakStatus.jailbroken { if (jailbreakStatus.failedChecks.contains { $0.check == .existenceOfSuspiciousFiles }) && (jailbreakStatus.failedChecks.contains { $0.check == .suspiciousFilesCanBeOpened }) { print("This is real jailbroken device") } } ``` ### Debugger detector module ```Swift let amIDebugged: Bool = IOSSecuritySuite.amIDebugged() ``` ### Deny debugger at all ```Swift IOSSecuritySuite.denyDebugger() ``` ### Emulator detector module ```Swift let runInEmulator: Bool = IOSSecuritySuite.amIRunInEmulator() ``` ### Reverse engineering tools detector module * **The simplest method** returns True/False if you just want to know if the device has evidence of reverse engineering ```Swift if IOSSecuritySuite.amIReverseEngineered() { print("This device has evidence of reverse engineering") } else { print("This device hasn't evidence of reverse engineering") } ``` * **Verbose & filterable**, if you also want the list of checks done ```Swift let reverseStatus = IOSSecuritySuite.amIReverseEngineeredWithFailedChecks() if reverseStatus.reverseEngineered { // check for reverseStatus.failedChecks for more details } ``` ### System proxy detector module Now you can also detect if an app is connected to VPN ```Swift let amIProxied: Bool = IOSSecuritySuite.amIProxied(considerVPNConnectionAsProxy: true) ``` ### Lockdown mode detector module ```Swift let amIInLockdownMode: Bool = IOSSecuritySuite.amIInLockdownMode() ``` ## Experimental features ### Runtime hook detector module ```Swift let amIRuntimeHooked: Bool = amIRuntimeHook(dyldWhiteList: dylds, detectionClass: SomeClass.self, selector: #selector(SomeClass.someFunction), isClassMethod: false) ``` ### Symbol hook deny module ```Swift // If we want to deny symbol hook of Swift function, we have to pass mangled name of that function denySymbolHook("$s10Foundation5NSLogyySS_s7CVarArg_pdtF") // denying hooking for the NSLog function NSLog("Hello Symbol Hook") denySymbolHook("abort") abort() ``` ### MSHook detector module ```Swift // Function declaration func someFunction(takes: Int) -> Bool { return false } // Defining FunctionType : @convention(thin) indicates a β€œthin” function reference, which uses the Swift calling convention with no special β€œself” or β€œcontext” parameters. typealias FunctionType = @convention(thin) (Int) -> (Bool) // Getting pointer address of function we want to verify func getSwiftFunctionAddr(_ function: @escaping FunctionType) -> UnsafeMutableRawPointer { return unsafeBitCast(function, to: UnsafeMutableRawPointer.self) } let funcAddr = getSwiftFunctionAddr(someFunction) let amIMSHooked = IOSSecuritySuite.amIMSHooked(funcAddr) ``` ### MSHook deny module ```Swift // Function declaration func denyDebugger(value: Int) { } // Defining FunctionType : @convention(thin) indicates a β€œthin” function reference, which uses the Swift calling convention with no special β€œself” or β€œcontext” parameters. typealias FunctionType = @convention(thin) (Int)->() // Getting original function address let funcDenyDebugger: FunctionType = denyDebugger let funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self) if let originalDenyDebugger = denyMSHook(funcAddr) { // Call the original function with 1337 as Int argument unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337) } else { denyDebugger() } ``` ### File integrity verifier module ```Swift // Determine if application has been tampered with if IOSSecuritySuite.amITampered([.bundleID("biz.securing.FrameworkClientApp"), .mobileProvision("2976c70b56e9ae1e2c8e8b231bf6b0cff12bbbd0a593f21846d9a004dd181be3"), .machO("IOSSecuritySuite", "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc")]).result { print("I have been Tampered.") } else { print("I have not been Tampered.") } // Manually verify SHA256 hash value of a loaded dylib if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.custom("IOSSecuritySuite")), hashValue == "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc" { print("I have not been Tampered.") } else { print("I have been Tampered.") } // Check SHA256 hash value of the main executable // Tip: Your application may retrieve this value from the server if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.default), hashValue == "your-application-executable-hash-value" { print("I have not been Tampered.") } else { print("I have been Tampered.") } ``` ### Breakpoint detection module ```Swift func denyDebugger() { // Set breakpoint here } typealias FunctionType = @convention(thin) ()->() let func_denyDebugger: FunctionType = denyDebugger // `: FunctionType` is a must let func_addr = unsafeBitCast(func_denyDebugger, to: UnsafeMutableRawPointer.self) let hasBreakpoint = IOSSecuritySuite.hasBreakpointAt(func_addr, functionSize: nil) if hasBreakpoint { print("Breakpoint found in the specified function") } else { print("Breakpoint not found in the specified function") } ``` ### Watchpoint detection module ```Swift // Set a breakpoint at the testWatchpoint function func testWatchpoint() -> Bool{ // lldb: watchpoint set expression ptr var ptr = malloc(9) // lldb: watchpoint set variable count var count = 3 return IOSSecuritySuite.hasWatchpoint() } ``` ## Security considerations Before using this and other platform security checkers, you have to understand that: * Including this tool in your project is not the only thing you should do in order to improve your app security! You can read a general mobile security whitepaper [here](https://www.securing.biz/en/mobile-application-security-best-practices/index.html). * Detecting if a device is jailbroken is done locally on the device. It means that every jailbreak detector may be bypassed (even this)! * Swift code is considered to be harder to manipulate dynamically than Objective-C. Since this library was written in pure Swift, the IOSSecuritySuite methods shouldn't be exposed to Objective-C runtime (which makes it more difficult to bypass βœ…). You have to know that attacker is still able to MSHookFunction/MSFindSymbol Swift symbols and dynamically change Swift code execution flow. ## Contribution ❀️ Yes, please! If you have a better idea or you just want to improve this project, please text me on [Twitter](https://twitter.com/_r3ggi) or [Linkedin](https://www.linkedin.com/in/wojciech-regula/). Pull requests are more than welcome! ### Special thanks: πŸ‘πŸ» * [kubajakowski](https://github.com/kubajakowski) for pointing out the problem with ```canOpenURL(_:)``` method * [olbartek](https://github.com/olbartek) for code review and pull request * [benbahrenburg](https://github.com/benbahrenburg) for various ISS improvements * [fotiDim](https://github.com/fotiDim) for adding new file paths to check * [gcharita](https://github.com/gcharita) for adding the Swift Package Manager support * [rynaardb](https://github.com/rynaardb) for creating the `amIJailbrokenWithFailedChecks()` method * [undeaDD](https://github.com/undeaDD) for various ISS improvements * [fnxpt](https://github.com/fnxpt) for adding multiple JB detections * [TannerJin](https://github.com/TannerJin) for MSHook, RuntimeHook, SymbolHook and Watchpoint Detection modules * [NikoXu](https://github.com/NikoXu) for adding file integrity module * [hellpf](https://github.com/hellpf) for fixing a dangling socket problem * [Ant-tree](https://github.com/Ant-tree) for improving hooking resistence * [izmcm](https://github.com/izmcm) for implementing the `amIReverseEngineeredWithFailedChecks()` method * [sanu](https://github.com/sanu) for new providing new file checks * [marsepu](https://github.com/marsepu) for a well-done PR with new improvements * [mkj-is](https://github.com/mkj-is) for a PR improving ISS performance πŸš„ * [LongXiangGuo](https://github.com/LongXiangGuo) for a PR adding the privacy manifest ## TODO * [ ] Research Installer5 and Zebra Package Manager detection ( Cydia Alternatives ) ## License See the LICENSE file. ## References While creating this tool I used: * πŸ”— https://github.com/TheSwiftyCoder/JailBreak-Detection * πŸ”— https://github.com/abhinashjain/jailbreakdetection * πŸ”— https://gist.github.com/ddrccw/8412847 * πŸ”— https://gist.github.com/bugaevc/4307eaf045e4b4264d8e395b5878a63b * πŸ“š "iOS Application Security" by David Thiel