iOSSecuritySuite Documentation

repository·master·Indexed 25 days ago

https://github.com/securing/iossecuritysuite

An advanced platform security and anti-tampering library written in pure Swift for iOS and iPadOS. It provides tools to detect jailbreaking, debuggers, emulators, reverse engineering tools, system proxies, VPNs, and Apple's Lockdown Mode. The library includes features for verifying file integrity, detecting runtime/symbol/MSHooking, and identifying breakpoints or watchpoints, aligning with OWASP MASVS standards.

Tokens
2.5K
Snippets
7
Records
9
Agent score
33%

What's inside iOSSecuritySuite

  1. Install iOSSecuritySuite

    master

    You can integrate iOSSecuritySuite into your iOS project using one of the following four methods:

    1. Add source: Manually add IOSSecuritySuite/*.swift files to your project.
    2. CocoaPods: Add pod 'IOSSecuritySuite' to your Podfile.
    3. Carthage: Add github "securing/IOSSecuritySuite" to your Cartfile.
    4. Swift Package Manager: Add the package via URL.

    Note: This library is intended for use on iOS/iPadOS and should not be used on Macs with Apple Silicon.

    .package(url: "https://github.com/securing/IOSSecuritySuite.git", from: "1.5.0")
  2. Configure Info.plist for Jailbreak Detection

    master

    The jailbreak detection module uses the canOpenURL(_:) method to query specific URL schemes. You must update your main Info.plist to include these schemes in the LSApplicationQueriesSchemes array to ensure detection works correctly.

    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>undecimus</string>
        <string>sileo</string>
        <string>zbra</string>
        <string>filza</string>
    </array>
  3. Verify File Integrity and Tampering

    master

    Verify if the application or its components have been tampered with using bundle IDs, mobile provisioning profiles, or Mach-O file hashes.

    Tamper Detection

    Pass an array of requirements (e.g., .bundleID, .mobileProvision, .machO) to amITampered(_:).

    Manual Hash Verification

    Use getMachOFileHashValue(_:) to verify the SHA256 hash of a specific dylib or the main executable (.default).

    // Detect tampering via multiple indicators
    if IOSSecuritySuite.amITampered([.bundleID("biz.securing.FrameworkClientApp"),
        .mobileProvision("2976c70b56e9ae1e2c8e8b231bf6b0cff12bbbd0a593f21846d9a004dd181be3"),
        .machO("IOSSecuritySuite", "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc")]).result {
        print("I have been Tampered.")
    }
    
    // Verify dylib hash
    if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.custom("IOSSecuritySuite")), hashValue == "6d8d460b9a4ee6c0f378e30f137cebaf2ce12bf31a2eef3729c36889158aa7fc" {
        print("I have not been Tampered.")
    }
    
    // Verify main executable hash
    if let hashValue = IOSSecuritySuite.getMachOFileHashValue(.default), hashValue == "your-application-executable-hash-value" {
        print("I have not been Tampered.")
    }
  4. Detect Runtime, Symbol, and MSHooking

    master

    iOSSecuritySuite includes experimental modules to detect various types of function hooking:

    • Runtime Hook Detection: Detects if a specific class method or function has been hooked using amIRuntimeHook(...).
    • Symbol Hook Denial: Prevents hooking of specific symbols (including Swift mangled names) using denySymbolHook(_:).
    • MSHook Detection: Verifies if a specific function address has been modified by MSHook using amIMSHooked(_:).
    • MSHook Denial: Attempts to restore the original function address using denyMSHook(_:).
    // Runtime Hook Detection
    let amIRuntimeHooked: Bool = amIRuntimeHook(dyldWhiteList: dylds, detectionClass: SomeClass.self, selector: #selector(SomeClass.someFunction), isClassMethod: false)
    
    // Symbol Hook Denial (use mangled names for Swift functions)
    denySymbolHook("$s10Foundation5NSLogyySS_s7CVarArg_pdtF")
    denySymbolHook("abort")
    
    // MSHook Detection
    typealias FunctionType = @convention(thin) (Int) -> (Bool)
    func getSwiftFunctionAddr(_ function: @escaping FunctionType) -> UnsafeMutableRawPointer {
        return unsafeBitCast(function, to: UnsafeMutableRawPointer.self)
    }
    let funcAddr = getSwiftFunctionAddr(someFunction)
    let amIMSHooked = IOSSecuritySuite.amIMSHooked(funcAddr)
    
    // MSHook Denial
    typealias FunctionType = @convention(thin) (Int)->()
    let funcDenyDebugger: FunctionType = denyDebugger 
    let funcAddr = unsafeBitCast(funcDenyDebugger, to: UnsafeMutableRawPointer.self)
    
    if let originalDenyDebugger = denyMSHook(funcAddr) {
         unsafeBitCast(originalDenyDebugger, to: FunctionType.self)(1337)
    } else {
         denyDebugger()
    }
  5. Detect Debugger, Emulator, and Reverse Engineering Tools

    master

    Use the following methods to detect common security threats:

    • Debugger: amIDebugged() returns true if a debugger is attached.
    • Debugger Denial: denyDebugger() attempts to prevent debugger attachment.
    • Emulator: amIRunInEmulator() returns true if the app is running in an emulator.
    • Reverse Engineering: amIReverseEngineered() returns true if common RE tools are detected.
    • Reverse Engineering (Verbose): amIReverseEngineeredWithFailedChecks() provides detailed check results.
    // Debugger
    let amIDebugged: Bool = IOSSecuritySuite.amIDebugged()
    IOSSecuritySuite.denyDebugger()
    
    // Emulator
    let runInEmulator: Bool = IOSSecuritySuite.amIRunInEmulator()
    
    // Reverse Engineering
    if IOSSecuritySuite.amIReverseEngineered() {
      print("This device has evidence of reverse engineering")
    }
    
    let reverseStatus = IOSSecuritySuite.amIReverseEngineeredWithFailedChecks()
    if reverseStatus.reverseEngineered {
       // check for reverseStatus.failedChecks for details
    }
  6. Detect Breakpoints and Watchpoints

    master

    Use these experimental modules to detect active debugging breakpoints or watchpoints.

    • Breakpoint Detection: Use hasBreakpointAt(_:functionSize:) to check if a breakpoint exists at a specific function address.
    • Watchpoint Detection: Use hasWatchpoint() to check for active watchpoints.
  7. Detect Jailbreak

    master

    iOSSecuritySuite provides several ways to detect if a device is jailbroken, ranging from simple boolean checks to verbose reporting of specific indicators.

    Simple Detection

    Returns true if the device is jailbroken.

    Verbose Detection

    Returns a status object containing a boolean and a failMessage string describing the detected indicators (e.g., sileo:// URL scheme detected).

    Filterable Detection

    Returns a status object that allows you to inspect specific failedChecks to distinguish between active jailbreaks and historical indicators.

    // Simple
    if IOSSecuritySuite.amIJailbroken() {
    	print("This device is jailbroken")
    }
    
    // Verbose
    let jailbreakStatus = IOSSecuritySuite.amIJailbrokenWithFailMessage()
    if jailbreakStatus.jailbroken {
    	print("This device is jailbroken")
    	print("Because: \(jailbreakStatus.failMessage)")
    }
    
    // Verbose & Filterable
    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")
        }
    }