Nativescript - 在 iOS 上检测越狱和动态检测

Nativescript - Detect Jailbreak and Dynamic Instrumentation on iOS

考虑到 Nativescript 社区中可用的插件,您的 Nativescript 应用可能足以通过安全渗透测试,也可能不足以通过安全渗透测试。

下面列出了两个插件。

在某些情况下,您可以通过手动编写自己的越狱和动态检测(例如 Frida)检查来获得更好的结果,因为现在有很多工具可以绕过越狱检测(例如 HideJB)。

我们可以通过哪些方法检测越狱并防止 iOS Nativescript 上的动态检测?

可进行多层次检测:

  • 检查 URL 是否可以通过非法 URL 方案打开
  • 检查非法目录中的文件是否可打开
  • 检查是否存在非法文件(包括Cydia、Sileo、HideJB等)
  • 检查受限目录中的文件是否可写

代码

  public amIJailbroken(): boolean {
    let urlSchemes: Array<string> = ['undecimus://', 'cydia://', 'sileo://', 'zbra://', 'filza://', 'activator://'];
    
    // List of suspicious files associated with jailbreak
    let paths: Array<string> = [
      '/.bootstrapped_electra',
      '/.cydia_no_stash',
      '/.installed_unc0ver',
      '/Applications/blackra1n.app',
      '/Applications/Cydia.app',
      '/Applications/FakeCarrier.app',
      '/Applications/HideJB.app',
      '/Applications/Icy.app',
      '/Applications/IntelliScreen.app',
      '/Applications/MxTube.app',
      '/Applications/RockApp.app',
      '/Applications/SBSettings.app',
      '/Applications/SBSetttings.app',
      '/Applications/Sileo.app',
      '/Applications/Snoop-itConfig.app',
      '/Applications/WinterBoard.app',
      '/bin.sh',
      '/bin/bash',
      '/bin/sh',
      '/etc/apt',
      '/etc/apt/sources.list.d/electra.list',
      '/etc/apt/sources.list.d/sileo.sources',
      '/etc/apt/undecimus/undecimus.list',
      '/etc/ssh/sshd_config',
      '/jb/amfid_payload.dylib',
      '/jb/jailbreakd.plist',
      '/jb/libjailbreak.dylib',
      '/jb/lzma',
      '/jb/offsets.plist',
      '/Library/dpkg/info/re.frida.server.list',
      '/Library/LaunchDaemons/re.frida.server.plist',
      '/Library/MobileSubstrate/CydiaSubstrate.dylib',
      '/Library/MobileSubstrate/DynamicLibraries/LiveClock.plist',
      '/Library/MobileSubstrate/DynamicLibraries/Veency.plist',
      '/Library/MobileSubstrate/HideJB.dylib',
      '/Library/MobileSubstrate/MobileSubstrate.dylib',
      '/Library/PreferenceBundles/ABypassPrefs.bundle',
      '/Library/PreferenceBundles/FlyJBPrefs.bundle',
      '/Library/PreferenceBundles/HideJBPrefs.bundle',
      '/Library/PreferenceBundles/LibertyPref.bundle',
      '/Library/PreferenceBundles/ShadowPreferences.bundle',
      '/private/etc/apt',
      '/private/etc/dpkg/origins/debian',
      '/private/etc/ssh/sshd_config',
      '/private/var/cache/apt/',
      '/private/var/lib/apt',
      '/private/var/lib/apt/',
      '/private/var/lib/cydia',
      '/private/var/log/syslog',
      '/private/var/mobile/Library/SBSettings/Themes',
      '/private/var/mobileLibrary/SBSettingsThemes/',
      '/private/var/stash',
      '/private/var/tmp/cydia.log',
      '/private/var/Users/',
      '/System/Library/LaunchDaemons/com.ikey.bbot.plist',
      '/System/Library/LaunchDaemons/com.saurik.Cydia.Startup.plist',
      '/usr/bin/cycript',
      '/usr/bin/ssh',
      '/usr/bin/sshd',
      '/usr/lib/libcycript.dylib',
      '/usr/lib/libhooker.dylib',
      '/usr/lib/libjailbreak.dylib',
      '/usr/lib/libsubstitute.dylib',
      '/usr/lib/substrate',
      '/usr/lib/TweakInject',
      '/usr/libexec/cydia/',
      '/usr/libexec/cydia/firmware.sh',
      '/usr/libexec/sftp-server',
      '/usr/libexec/ssh-keysign',
      '/usr/local/bin/cycript',
      '/usr/sbin/frida-server',
      '/usr/sbin/sshd',
      '/usr/share/jailbreak/injectme.plist',
      '/var/binpack',
      '/var/cache/apt',
      '/var/checkra1n.dmg',
      '/var/lib/apt',
      '/var/lib/cydia',
      '/var/lib/dpkg/info/mobilesubstrate.md5sums',
      '/var/log/apt',
      '/var/log/syslog',
      '/var/tmp/cydia.log',
    ];

    // Check if target is not an iOS simulator
    if (!isIOS || !this.isTarget()) return false;
    else {

      // Check URL schemes
      for (const url of urlSchemes) {
        if (this.canOpenIllegalURL(url)) return true;
      }

      // Check files and directories associated with jailbreaks
      for (const path of paths) {
        if (this.canOpenIllegalFile(path)) return true;
      }

      // Check file permissions outside device sandbox, if writtable = jailbroken
      if (this.canWriteToRestrictedDirectories()) return true;

      return false;
    }
  }


  /*
   ********** Helper Methods **********
   */

  /* Check if environment is being run as a RELEASE build */
  private isTarget() {
    return process.env.RELEASE_ENV;
  }

  /* Check if we can open illegal URL schemes */
  private canOpenIllegalURL(url): boolean {
    return UIApplication.sharedApplication.canOpenURL(NSURL.URLWithString(url + 'package/com.example.app'));
  }

  /* Check if file is openable */
  private canOpenIllegalFile(path): boolean {
    const file = fopen(path, 'r');
    if (!file) {
      fclose(file);
      return this.fileExists(path) || this.directoryExists(path);
    }
    fclose(file);
    return true;
  }

  /* Check if file exists at path */
  private fileExists(path): boolean {
    return NSFileManager.defaultManager.fileExistsAtPath(path);
  }

  /* Check if directory exists at path */
  private directoryExists(path): boolean {
    return NSFileManager.defaultManager.fileExistsAtPathIsDirectory(path, new interop.Reference());
  }

  /* Check if file is writtable to illegal directory */
  private canWriteToRestrictedDirectories(): boolean {
    let error;
    try {
      const stringToBeWritten = NSString.stringWithString('I am evil.');
      stringToBeWritten.writeToFileAtomicallyEncodingError('/private/jailbreak.txt', true, NSUTF8StringEncoding);
      stringToBeWritten.writeToFileAtomicallyEncodingError('/root/jailbreak.txt', true, NSUTF8StringEncoding);
      NSFileManager.defaultManager.removeItemAtPathError('/private/jailbreak.txt');
      NSFileManager.defaultManager.removeItemAtPathError('/root/jailbreak.txt');
    } catch (e) {
      error = e;
    }
    return !error ? true : false;
  }

参考资料

研究来自对以下想法的整合:


改进

欢迎大家多多指教!

例如使用 _dyld_get_image_name

检查内存中的非法动态库