首页
社区
课程
招聘
[原创]深入理解IOS重签名检测
发表于: 2025-6-10 12:31 931

[原创]深入理解IOS重签名检测

2025-6-10 12:31
931

iOS代码签名是苹果生态中安全机制的核心组成部分,其目的在于:

确保应用来源可信;

保证应用在分发、安装、运行过程中未被篡改;

强化沙箱隔离与权限控制;

实现应用追踪、授权和安全限制(如调试权限、Entitlements 等);

iOS 系统是一个高度封闭的移动操作系统。苹果采用“强制签名”的机制:所有运行在设备上的应用、动态库、系统组件等,都必须被签名并被信任。这是苹果构建其安全生态(如 App Store 审核、企业分发限制、隐私保护等)的基础。

没有合法签名的应用无法在未越狱的设备上运行。

防止第三方恶意篡改应用(如注入、重打包)

防止未授权的调试、注入、越权操作

限制破解行为(如破解付费、注入钩子、动态修改)

iOS 签名依赖苹果颁发的证书链,主要包括:

类型

用途

签名是用私钥进行的;

设备和系统在运行时使用公钥验证签名的合法性

是 .plist 格式的声明文件,告知系统你的应用需要使用哪些敏感能力(如 iCloud、Push、调试等);

这些权限需要与签名证书的能力匹配;

如果签名时声明了未授权的 Entitlements,运行会失败。

苹果使用一种称为 Code Signing Blob 的结构来封装签名信息,包含以下几个部分:

这是签名的核心结构,内容包括:

每个段(segment)或文件的哈希(Code Slot)

主可执行文件的哈希摘要(Main Executable Digest)

应用标识符(Identifier)

版本号、平台标识

Team ID(开发团队标识)

Entitlements hash(匹配授权)

包含:

证书链(Developer + WWDR + Root CA)

签名数据本身(对 Code Directory 的签名)

为了防止修改 Info.plist 中的关键字段(如 CFBundleIdentifier)

系统验证 Entitlements 的 hash 是否匹配签名时的声明。

在 Apple Developer 网站上创建 App ID;

使用 Xcode 或 Keychain 创建 CSR(证书请求);

苹果签发证书后下载并导入;


在 IOS APP的Macho文件中,LC_CODE_SIGNATURE类型的 load commands与代码签名相关,通过 MachoView打开这个文件可以看到:

签名数据位于文件偏移 0x2EBB200处,数据长度是0x1349E0

上述地址实际指向的是一个名为 SC_SuperBlob的结构体数据,数据定义如下:

第一个字段 magic是类型标记,固定为 0xfade0c00,第二个字段 length是这个 SC_SuperBlob数据的总长度,count是结构体中 CS_BlobIndex数据的个数。

CS_BlobIndex表示的是数据的类型和该类型数据在签名数据中的偏移,定义如下:

上图数据中共有 6 个 BlobIndex数据,如下图:


BlobIndex的 type 类型枚举如下:

BlobIndex偏移指向的是SC_GenericBlob结构体数据,定义如下:

第一个字段是类型标记,用于标记该数据类型。data字段才是实际的数据内容,长度通过 length 字段决定。

magic 字段的枚举值定义:

我们通过上面的 BlobIndex类型的排列顺序,逐个分析。

第一个 BlobIndex的 type 是 0,即 CSSLOT_CODEDIRECTORY_SHA1,表示存放的是 CodeDirectory数据,偏移地址是 3C,实际地址就是 0x2ebb23c.

CodeDirectory数据是签名的重要组成部分,里面包含了主 macho 文件代码段和数据段的哈希值,用于防止代码或数据被篡改。


这里 hashType = 0x1,以及 hashSize = 0x14,表示使用的是 sha1算法,哈希串长度是 20 个字节。

hashOffset值是 0x3A7B6,位于文件偏移 0x2ef59f2, 即地址 0x2ef59f2开始的 20 字节表示的是 TEXT段的第一个page的 sha1 哈希值

这里 TEXT段文件偏移是 0,从文件的第 0 个字节开始,计算连续 0x1000个字节的 sha1值

符合hashOffset中记录的哈希值:


nSpecialSlots字段记录特殊区域或者文件的哈希值,这个值是负数

CodeResources文件中保存了 APP中各种文件的哈希值,用于校验 APP中的资源文件是否被篡改。

entitlement数据定义了 APP运行时需要哪些权限。

代码检测签名内容中的 CodeDirectory数据:


1、检测 plist篡改

2、检测 CodeResources文件篡改

3、检测 entitlement篡改

4、检测代码段篡改

5、检测资源文件篡改:

上述代码可以检测资源数据或代码是否被篡改,那么如果同时篡改了CodeDirectory呢?(CMS签名中会检验CodeDirectory的哈希


第二个 BlobIndex的 type 是 2,即 CSSLOT_REQUIREMENTS,用于说明签名对运行条件的要求。

结构体定义如下:

实际数据位于 0x2f300a2

上述数据中定义了一个 Requirement,位于地址 0x2f300b6,Requirement 的定义如下:

expr数据是 Requirement Language 编译后的二进制。


第三个 BlobIndex的 type 是  5,即 CSSLOT_ENTITLEMENTS,用于权限标记。地址位于 0x2f30102

实际数据位于 0x2f3010a,长度是 0x2d8

导出:

数据内容:



第四个 BlobIndex的 type 是  7,是 CSSLOT_DER_ENTITLEMENTS。应该是使用 asn1编码后的 ENTITLEMENTS数据。

导出:

解析 asn1数据:

第五个 BlobIndex的 type 是  0x1000,是 CSSLOT_CODEDIRECTORY_SHA256。同 CSSLOT_CODEDIRECTORY_SHA1,不再分析。

第六个 BlobIndex的 type 是  0x10000,是 CSSLOT_SIGNATURESLOT,是详细的 CMS 签名数据。地址位于 0x2feb590

实际 CMS签名数据位于 0x2feb598,长度是 0x1126,导出数据:

解析:

这是使用 asn1编码的详细数据,里面包含了签名的详细信息,包括证书链、签名时间、CodeDirectory 哈希等。


什么是 ASN1

ASN.1(Abstract Syntax Notation dotone),抽象语法标记。是定义抽象数据类型形式的标准,描绘了与任何表示数据的编码技术无关的通用数据结构。抽象语法使得人们能够定义数据类型,并指明这些类型的值。抽象语法只描述数据的结构形式,与具体的编码格式无关,同时也不涉及这些数据结构在计算机内如何存放。


cms签名结构解析

1、定义标签

cms签名数据以 ASN1_TAG_SEQUENCE类型的ContentInfo开始,这个 sequence 包含两个数据:ContentType 和 Content

解析的入口:

先解析 ContentType,支持 1.2.840.113549.1.7.2 和 1.2.840.113549.1.7.1 两种签名数据解析。然后通过 cms_parse_signData函数解析签名数据。

继续看 Content内部是什么结构:

Content里面只有一个 sequence 类型的 SignedData数据,SignedData里包含版本、签名算法、证书链以及签名信息。


[培训]科锐逆向工程师培训第53期2025年7月8日开班!

最后于 2025-6-10 12:41 被CCTV果冻爽编辑 ,原因:
收藏
免费 50
支持
分享
最新回复 (27)
雪    币: 104
活跃值: (5701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
6666
2025-6-10 14:04
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2025-6-10 23:02
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
666
6天前
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
666
6天前
0
雪    币: 1837
活跃值: (3680)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
666
6天前
0
雪    币: 1116
活跃值: (1121)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
666
6天前
0
雪    币: 8537
活跃值: (3557)
能力值: ( LV6,RANK:85 )
在线值:
发帖
回帖
粉丝
8
1
6天前
0
雪    币: 7761
活跃值: (5157)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
感谢分享
6天前
0
雪    币: 30
活跃值: (1735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
666
5天前
0
雪    币: 1057
活跃值: (840)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
666
5天前
0
雪    币: 1431
活跃值: (1460)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
学习一下
5天前
0
雪    币: 7162
活跃值: (22756)
能力值: ( LV12,RANK:550 )
在线值:
发帖
回帖
粉丝
13
看看
5天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
666
5天前
0
雪    币: 3065
活跃值: (4422)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
感谢分享
5天前
0
雪    币: 406
活跃值: (100)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
1
5天前
0
雪    币: 42927
活跃值: (65707)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
17
4天前
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
66
4天前
0
雪    币: 0
活跃值: (100)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
666
4天前
0
雪    币: 5164
活跃值: (4755)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
666
4天前
0
雪    币: 90
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
666666666
3天前
0
雪    币: 30
活跃值: (1186)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
1
3天前
0
雪    币: 204
活跃值: (35)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
13212
2天前
0
雪    币: 482
活跃值: (400)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
666
1天前
0
雪    币: 424
活跃值: (665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
12312
1天前
0
游客
登录 | 注册 方可回帖
返回