绕过 iOS 代码签名验证 && ldid

目录

    • 绕过 iOS 代码验证
    • ldid
    • Homebrew

绕过 iOS 代码验证

iOS 的代码验证分为 2 个环节:

  1. 签名验证,用于确认代码是经过苹果授权的
  2. 有效验证,用于确认代码没有被修改过

以下内容是基于 saurik 在 Cydia 中编写的一个文档,他文章的另一个版本的名称为:Bypassing iPhone Code Signatures

苹果要求 iOS 设备上的所有代码都要经过苹果的签名。这主要是为了让通过苹果应用商店(Apple App Store)下载和安装的 App 不能再下载和运行未经苹果授权的其他 App(以让 Apple App Store 没有竞争对手)。为了解决这个问题(从而将我们自己的代码安装到 iOS 设备上),越狱工具在内核中添加了对签名验证的补丁

然而,代码验证的另一半问题是,MachO 二进制文件中包含了许多用于有效验证的 SHA1 哈希值,内核的许多位置都会对这些哈希值进行检查。在内核中对验证 MachO 二进制哈希值的所有位置添加补丁对我们来说是边际效益递减的:因为苹果在内核中的其他位置添加对 MachO 二进制文件的哈希值的验证是很容易的,而我们跟踪苹果在内核中做出的改变是很困难的

这意味着至少我们仍然需要在代码验证流程中,内核有效验证这一环节,为计算出用于应付内核有效验证的哈希值而付出努力。目前有三个可行的选项

  • 选项 1:自签名

    这种方法是最容易理解的:使用苹果的 codesign 工具对 MachO 二进制文件进行签名。因为位于内核中的签名验证检查已经被破解了,所以开发者可以使用任意证书来对 MachO 二进制文件进行签名,而不仅仅是由苹果所批准的开发者证书。有关如何制作自签名证书的说明,你可以从苹果的网站上阅读这篇文章:Obtaining a Signing Identity

    在 Mac 的终端执行以下命令:

    codesign -fs "Name" Program
    scp Program mobile@iphone:
    
  • 选项 2:伪签名

    如果你没有 Mac 电脑,则无法使用上一个选项。整个 codesign 的流程不仅需要 Mac,还需要桌面访问,因为在某种程度上,codesign 算是一个图形实用工具(codesign 通过 Keychain 获取签名证书时,Keychain 可能会提示输入密码的对话框)。为了解决这个问题,saurik 编写了一个名为 ldid 的工具,除了其他公功能之外,ldid 还可以生成供 Apple 的 iOS 内核进行有效性检查的 SHA1 哈希值。这个工具可以使用 Cydia 或 APT 轻松地安装在 iPhone 上

    在 iPhone 的终端执行以下命令:

    apt-get install ldid
    scp user@desktop:Program .
    ldid -S Program
    
  • 选项 3:禁用检查

    最后,一个便于开发的选项就是禁用检查。从技术上讲,禁用检查不仅会禁用对代码验证的检查,也会禁用对其他一些安全机制的检查。虽然我(saurik)在这种状态下运行我的 iPhone 已经有一段时间了,但是我(saurik)听说在某些配置中它会导致问题:最大的问题就是无法连接到不安全的 WiFi 网络中。禁用检查是通过使用 sysctl 命令停用 enforcement 来实现的,并且可以通过重置变量或者重新启动手机来重新启用

    在 iPhone 的终端执行以下命令:

    sysctl -w security.mac.proc_enforce=0 security.mac.vnode_enforce=0
    

ldid

  • 简介

    ldid 是由 saurik 制作的一个工具,用于方便地修改 iOS 二进制可执行文件的授权。ldid 还为 iOS 二进制可执行文件的签名生成 SHA1SHA256 的哈希值,以让 iPhone 内核执行修改后的 iOS 二进制可执行文件。ldid 在 Cydia 中的包名是 Link Identity Editor

    项目地址(https://git.saurik.com/ldid.git)

  • 用法

    ldid -e :转储 iOS 二进制可执行文件中的 entitlements 文件

    ldid -Sent.xml :设置 iOS 二进制可执行文件的授权,其中 ent.xml 是指 entitlements 文件的路径

    ldid -S :在不使用 entitlements 文件的情况下,对 iOS 二进制可执行文件进行伪签名

    例如,如果开发者想将桌面上名为 Entitlements.xml 的文件中的权限添加到当前目录的 debugserver 中,则开发者可以执行:
    ldid -S/Users/you/Desktop/Entitlements.xml ./debugserver

  • 帮助手册

    LDID(1) 		FreeBSD General Commands Manual(FreeBSD 通用命令手册) 	       LDID(1)
    
    NAME(名称)
    
    	ldid – Link Identity Editor
    
    SYNOPSIS(摘要)
    
    	ldid [-aDdehMPqu] 
    		 [-Acputype:subtype]
    		 [-C[adhoc | enforcement | expires | hard | host | kill | library-validation | restrict | runtime]]
    		 [-Kkey.p12] 
    		 [-r | -Sfile | -s] 
    		 [-Ttimestamp] 
    		 file ...
    
    DESCRIPTION(说明)
    
    	ldid 将 SHA1 和 SHA256 哈希值添加到 Mach-O 文件中,这样 Mach-O 文件就可以运行在具有(有效验证)但没有(签名验证)的系统上
    
    	-a			# 以十六进制的形式打印 CPU 类型和 CPU 子类型
    
    	-Acputype:subtype 
    				# 当与 -a, -D, -e, -h, -q, -u 一起使用时,只作用于 cputype 和 subtype 指定的片(slice)。cputype 和 subtype 都应该是整数
    
    	-C[adhoc | enforcement | expires | hard | host | kill | library-validation | restrict | runtime]
    				# 指定要嵌入到代码签名中的选项标志。有关这些选项的详细信息,请查看 codesign(1)
    
    	-D			# 重置 cryptid
    
    	-d			# 如果二进制可执行文件中存在 cryptid,则打印它。由于兼容性的原因,此指令也充当 -h 的功能,但这将在未来版本中被删除
    
    	-e			# 用标准输出(stdout)打印每个片(slice)中的 entitlements,或者打印由 -A 指定的片(slice)中的 entitlements
    
    	-h			# 用标准输出(stdout)打印与签名有关的信息,例如:hash types、flags、CDHash、CodeDirectory version
    
    	-Kkey.p12	# 使用 key.p12 文件中的证书信息进行签名(.p12 文件中存储的是:开发者证书 + 对应的专用私钥)
    				# 这将给二进制可执行文件一个有效的签名,以便它可以运行在具有签名验证的系统上。key.p12 文件必须不能有密码
    
    	-M			# 当与 -S 一起使用时,将合并新的 entitlements 和现有的 entitlements,而不是用新的 entitlements 替换现有的 entitlements
    				# 这对于向少数二进制可执行文件添加一些特定的权限很有用
    
    	-P			# 将 Mach-O 文件标记为 platform binary
    
    	-Qfile		# 向二进制可执行文件中嵌入在参数 file 所指定文件中所找到的 requirements 
    
    	-q			# 打印嵌入在二进制可执行文件中的 requirements
    
    	-r			# 删除 MachO 文件中的签名
    
    	-S[file]	# 对 MachO 二进制文件进行伪签名。如果指定了 file 参数,则将在 file 参数所标识的文件中找到的 entitlements 嵌入到 MachO 文件中
    
    	-s			# 对 MachO 二进制文件进行重签名,同时保留现有的 entitlements
    
    	-Ttimestamp	# 当对 dylib 进行签名时,可以使用参数 -Ttimestamp 将指定的时间戳设置给 dylib 的 timestamp 字段
    				# 参数 -Ttimestamp 指定的时间戳应该是一个以秒为单位的 UNIX 时间戳
    				# 如果参数 -Ttimestamp 指定的时间戳是个破折号("-"),则 dylib 的 timestamp 字段将被设置为其 Mach-O header 的哈希值
    
    	-u			# 如果二进制可执行文件有跟 UIKit.framework 进行链接,则打印与二进制可执行文件链接的 UIKit.framework 的版本
    
    EXAMPLES(示例)
    
    	命令:ldid -S file
    	说明:在不使用 entitlements 的情况下,对参数 file 所指定的二进制可执行文件进行伪签名
    	
    	命令:ldid -Cadhoc -K/path/to/key.p12 -Sent.xml file
    	说明:将使用(/path/to/key.p12 中的 key)和(在 ent.xml 中找到的 entitlements)对 file 参数所指定的二进制可执行文件进行签名,并将其标记为一个 adhoc 签名
    	
    	命令:ldid -Sent.xml -M file
    	说明:将 ent.xml 中的 entitlements 添加到参数 file 所指定的二进制可执行文件的 entitlements 中
    
    	命令:ldid -e file > ent.xml
    	说明:将参数 file 所指定的二进制可执行文件中每个 CPU 片(slice)的 entitlements 保存到 ent.xml 中
    
    SEE ALSO(请参考)
    
         codesign(1)
    
    HISTORY(历史)
    
    	ldid 是由 Jay Freeman (Saurik) 所编写的
    	iPhoneOS 1.2.0 和 2.0 的支持是在 200846 日添加的
    	-S 是在 2008613 日增添加的
    	对 SHA256 的支持是在 2016825 日添加的,修复了对 iOS 11 的支持
    	对 iOS 14 的支持是在 2020731 日由 Kabir Oberai 添加的
    	对 iOS 15 的支持是在 2021611 日添加的
    
    iPhoneDevWiki			October 8, 2021(2021 年 108 日) 		 iPhoneDevWiki
    
  • 安装

    通过 Homebrew、Fink 或者 source:

    git clone https://github.com/sbingner/ldid
    cd ldid
    git submodule update --init
    ./make.sh
    cp -f ./ldid $THEOS/bin/ldid
    
  • 镜像地址

    https://ac3xx.com/ldid
    https://joedj.net/ldid
    https://jontelang.com/guide/chapter2/ldid.html

Homebrew

  • 简介

    Homebrew 是一款 macOS 平台下的软件包管理工具,拥有安装、卸载、更新、查看、搜索等很多实用的功能。简单的一条指令,就可以实现包管理,而不用开发者关心各种依赖和文件路径的情况,十分方便快捷

    官网地址

  • 安装 & 卸载

    # Homebrew 安装脚本
    /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"
    
    # Homebrew 卸载脚本
    /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/HomebrewUninstall.sh)"
    
  • 常用命令

    # 更新 Homebrew
    brew update
    
    # 查询当前 Homebrew 版本
    brew -v
    
    # 查询 Homebrew 帮助信息
    brew -h
    
    # 安装给定的包
    brew install <packageName>
    
    # 卸载给定的包
    brew uninstall <packageName>
    
    # 更新给定的包
    brew upgrade <packageName>
    
    # 查询给定的包
    brew search <packageName>
    
    # 查询给定包的信息
    brew info <packageName>
    
    # 查询已安装的包的列表
    brew list
    
    # 查看可清理的旧版本包(仅查看,不执行清理)
    brew cleanup -n
    
    # 清理所有包的旧版本
    brew cleanup
    
  • 更换阿里云镜像源进行加速

    执行 brew install 命令安装软件包的时候,软件包的下载速度跟以下 3 个仓库的地址有关:

    1. brew.git
    2. homebrew-core.git
    3. homebrew-bottles

    因为这 3 个仓库的默认地址都在国外,所以下载速度非常感人。建议将这 3 个仓库的地址切换到国内。以切换到阿里云镜像源为例:

    ① 更换 brew.git

    cd "$(brew --repo)"
    git remote set-url origin https://mirrors.aliyun.com/homebrew/brew.git
    

    ② 更换 homebrew-core.git

    cd "$(brew --repo)/Library/Taps/homebrew/homebrew-core"
    git remote set-url origin https://mirrors.aliyun.com/homebrew/homebrew-core.git
    

    ③ 执行 brew update 命令,更新 Homebrew

    ④ 更换 homebrew-bottles

    # 如果默认 shell 是 zsh,则执行以下两条命令
    echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.zshrc
    source ~/.zshrc
    
    # 如果默认 shell 是 bash,则执行以下两条命令
    echo 'export HOMEBREW_BOTTLE_DOMAIN=https://mirrors.aliyun.com/homebrew/homebrew-bottles' >> ~/.bash_profile
    source ~/.bash_profile
    
  • 相关的图形界面操作软件

    Cakebrew

    LaunchRocket

你可能感兴趣的:(iOS,安全攻防,1024程序员节)