一、前 言
二、函数介绍
三、行为检测与漏洞分析
四、总 结
近期,符号链接在本地提权利用中的比重逐渐增加。无论是macOS、Windows、Linux操作系统,还是其安装的第三方应用程序,都可能使用符号链接。越是底层的函数调用,开发者越需要关注相关漏洞模式及函数参数传递的安全性。
一个漏洞的产生通常是由于在使用API函数时未充分考虑潜在的漏洞模式。如果在执行过程中存在恶意行为对这些函数进行修改,防护措施不严格会导致执行流程走向错误的分支,最终被攻击者利用。下面将以open
和rename
两个基础函数为例,介绍多个相关漏洞。
OPEN函数
open
函数是C语言中的一个基础函数,主要用于打开文件并返回一个文件描述符。其他函数可以通过这个文件描述符对文件或目录进行读写操作。其函数原型如下:
open
函数存在三个参数:
mode: 可以在调用时省略第三个参数mode,在创建新文件的时候,会通过此参数修改新文件的文件属性;
pathname: 用于一个指向文件或者文件夹的路径,可以为绝对路径也可以为相对路径;
flag: 作为open函数最重要的一环,参数flag能赋予的值有各种,不同的flag字段代表着不同的功能。
RENAME函数
rename
函数作为C语言中的一个基础函数,主要用于处理文件或目录的移动和重命名。该函数不会修改文件或目录的属性。其函数原型如下:
rename
函数只有两个参数,一个是指向旧文件的字符串指针,另一个是指向想要修改后的新文件字符串指针。无论是哪一个参数,它都不会去检测访问路径是否是符号链接,即目录是通过符号链接访问的依旧会执行。反之,若是指向的最终文件/目录是符号链接,rename
不会对其访问,只有在访问过程中的目录路径属于符号链接时才会进入。
通常,对于系统调用号的检测,在Linux上有成熟的方法。在macOS上,也有专门用于监控文件行为的系统命令fs_usage
。fs_usage
可以实时监听系统用户态上对文件的各种操作行为,包括文件状态获取、读写操作以及页面交换等。通过使用fs_usage
,开发者和安全研究人员能够详细地跟踪和分析文件相关的系统活动,从而更好地理解和诊断文件操作中的问题。
如上图所示,可以配合grep
命令获取对应进程的相关行为。通过该命令,可以简化对文件流处理的追踪,直接从所执行的系统行为或系统调用中定位到具体的代码。
对于编程语言而言,它们提供了许多封装好的API函数。在Objective-C和Swift中,也有相当多的函数底层实现可以进行分析。这些封装好的API函数不仅简化了开发过程,还为开发者提供了强大的功能。通过对这些底层实现的分析,可以更好地理解其工作原理,并在必要时进行优化或调试。
此处编写一个使用moveItemAtPath:toPath:
函数的示例代码,并为rename
函数设置断点。通过这种方式,可以发现最终实现也会调用rename
函数。
CVE-2020-9900 文件写入自定义目录
在macOS系统中,后台存在一个以root权限启动的进程,即CrashReporter
。该进程负责收集系统各种崩溃报告和日志,并将其存放于/Library/Logs/DiagnosticReports
和~/Library/Logs/DiagnosticReports
目录中。这两个目录的所属用户是_analyticsusers
,而默认用户通常属于admin用户组,因此默认用户拥有读写上述两个目录的权限。
如上图所示,系统会根据报告生成的时间和进程名等字段,将崩溃报告存放于指定目录中。在这些目录中,存在一个名为Retired
的子目录。报告的存放时间是有期限的,当报告超过这个期限时,另一个以root权限启动的进程SubmitDiagInfo
会将旧报告移动到Retired
目录中。由于SubmitDiagInfo
同样是以root权限运行的进程,在没有沙箱等安全规则干扰的情况下,它在访问相关root权限的目录或文件时不会因为权限不足而受到限制。
而root权限的 而此处选择了 回退到旧版本系统时,可以通过加载的 CVE-2023-32407 同目录rename函数写入自定义目录 两个不同的目录,一个作为子目录的存在,对于 在之前复现历史CVE的时候,笔者写了个简易的demo用来测试 因此 若是在 若是在 若在 利用 在Music.app启动之初,进程会加载 它可以指向一个文件路径,在 所传入的 若 所以 在 前面两个历史CVE是对于 CVE-2020-3830 任意文件覆盖 当用户在 macOS 上安装app时,系统都会将其记录到名为 根据 通过查看对应文件及当前文件夹的属性可以发现,目录属于admin用户组,同时默认用户是隶属于admin用户组其中一员。 而默认用户可以在此目录进行读写修改,那么系统记录所使用的 最终修复则是将相关写入行为在进程的临时文件夹中操作,而对应文件夹则是会被Sandbox所保护,无法在其中进行修改文件的行为,写入完成则会通过 CVE-2023-32428 bacmalloc 如此简单的符号链接,开发者怎么能想不到呢?所以在使用 若是设置了该字段,如CVE-2020-3830这般则不会被允许打开对应文件并访问软链接所指向的路径所对应的文件,但是 CVE-2023-32428则是由于忽视这点而导致的,macOS系统中存在一个系统库 首先会使用一次 最开始作者想要尝试通过预测文件名来进行任意目录写文件行为,而当传入的路径足够长的时候,最终文件名会发生截断。如下所示,此处可以拥有一个向任意目录写入名为s文件的原语。 但是因为没有合适的目录进行利用,故搁置。 最终利用SubmitDiagInfo
进程会将旧日志文件迁移到Retired
目录中。对于DiagnosticReports
目录,默认用户具有读写权限,因为该目录所属用户_analyticsusers
属于admin用户组。因此,可以修改Retired
目录的指向,使其指向一个特定的目录。当SubmitDiagInfo
进程执行淘汰旧报告的操作时,会将伪造的日志文件迁移到其他默认用户无权写入但root权限可写的目录中。/etc/periodic
目录,可以存放任意扩展名的文件,然后按照对应的存放目录,可以实现按周期执行。framework
定位到,进程在迁移文件时并没有考虑周全,忽略了对Retired
目录是否为符号链接以及其指向其他目录的检测,进程直接使用了相关函数进行文件移动。在Objective-C中,这些封装好的函数也仅仅是作为一个API函数。rename
函数确实很容易通过控制子目录的符号链接指向,从而实现任意文件拷贝,那么对于rename
函数新旧文件路径处理都处于同一个目录呢?rename
函数:ABC
目录和RESULT
目录是一个常规文件夹,MMM
是一个指向RESULT
目录的符号链接。在代码进行rename
之前,会先设置一个raceStart
的符号,通知另一侧的多线程让ABC
目录和MMM
目录进行原子交换,交换一次就是ABC
目录变为指向RESULT
目录的符号链接,而MMM
目录变为保存有FMYY
文件的常规文件夹。rename
和renameatx_np
的竞争可以有三种情况:rename
函数之前,目录属性发生交换,那么OLD_PATH
获取不到vnode
节点,rename
函数失败从内核返回;rename
函数之后,目录属性发生交换,那么行为已经发生,那么SuccessFMYY
文件会存放在MMM
文件夹;rename
函数执行过程中,目录属性发生了变化,使得ABC
目录被切换为指向RESULT
目录的符号链接,那么NEW_PATH
此时获取的文件夹节点将变为RESULT
目录。因此,rename
操作会在RESULT
目录下创建一个新的名为SuccessFMYY
的节点。Metal.framework
框架,其中存在使用环境变量MTL_DUMP_PIPELINES_TO_JSON_FILE
。Metal.framework
中通过getenv
函数获取对应变量,并调用NSFileManager
类中的createFileAtPath
方法。filePath
则是由MTL_DUMP_PIPELINES_TO_JSON_FILE
变量控制。如果对应文件存在,则会导致覆盖原文件并创建对应文件名。MTL_DUMP_PIPELINES_TO_JSON_FILE
指向/DIR/FILENAM
E,目录有效则会在/DIR/
目录下,创建随机文件名的一个文件<.dat.nosyncXXXX.XXXXXX>
,并写入数据到此文件中,最后再将此文件通过rename
函数修改为当前目录下FILENAME
文件。因为是同目录中,而rename
可能会被认为无法如前一个漏洞一样,进行任意位置迁移,但是根据上述构造的demo可知,当rename
函数在第二次取出目录节点的过程中,能够存在二次取目录节点的行为,可以说明这里rename
函数本身之内能进行TOCTOU攻击。rename
函数在使用的时候,是不会检测相关的符号链接的,因此可以引出同一族的其他函数如下:renamex_np
函数和renameatx_np
函数的时候,可以通过添加flag位RENAME_NOFOLLOW_AN
Y进行检测,它会阻断路径中所有的符号链接。rename
函数而言,文件迁移的行为中,本地攻击者可以通过竞争攻击,导致最终写入的路径发生变化,限制之一是需要控制对目录的删除创建权限,那么对于open
函数呢?open
函数在打开一个文件的时候,可以直接访问软链接指向的文件,最简单的方式就是控制传入给open
函数的文件路径,经由特权进程,则可以向特定的文件中写入特定的内容。InstallHistory.plist
的文件中,该文件位于/Library/Receipts
。例如当从AppStore安装QQ音乐应用的时候,安装完成,则会将安装的应用相关信息记录在此文件中。fs_usage
可以监控到是由installd进程进行写入的:InstallHistory.plist
文件,若是被用户修改为一个指向其他文件的符号链接,那么在下一次安装应用的时候,安装完成,会将安装记录追加到符号链接所指向的任意文件中,但是由于内容不可控,所以只能作为任意文件覆盖为不可控内容。renameat
函数拷贝到指定目录中。open
函数的时候,自然考虑到了一个标志位字段,而其中一个字段则是名为 O_NOFOLLOW
,其功能如下。它不允许追随文件是符号链接指向其他文件,但是,这么做就能遏制住符号链接的使用吗?O_NOFOLLOW
字段的出现存在一个忽略的点,即O_NOFOLLOW
字段并不会去检测整个路径中的父级目录是否使用符号链接指向特定的目录,若是能控制访问过程中的目录,则O_NOFOLLOW
字段的功能则会失效,从而引发进一步的漏洞产生。MallocStackLogging.framework
,它在被加载之后,会去检测环境变量的存在,其中存在一个特殊的环境变量MallocStackLoggingDirectory
,它将会在环境变量所对应的目录中,写入一个随机文件,用来记录相关数据。作者所述:access
函数来检测目标目录,再使用open
函数进行文件的创建并返回一个文件描述符,open
函数虽然使用了O_CREAT
字段创建文件,但是同时使用了O_EXCL
文件,因此无法覆盖已经存在的文件;第二点则是使用了O_NOFOLLOW
字段。由上可知,在能控制路径的情况下,O_NOFOLLOW
字段所存在的理由已经告破,因为可以通过切换父级目录来进行绕过;第三点则是open
函数的第三个参数mode
通常会被忽略,但是这里也是按照安全的0o700来进行创建的。
第二次尝试利用的时候,作者发现open
函数不存在O_CLOEXEC
属性,而O_CLOEXEC
属性的作用如下:
定义
O_CLOEXEC
是一个常量,通常在 <fcntl.h> 头文件中定义。它可以与其他打开标志(如 O_RDONLY
,O_WRONLY
等)一起使用。
使用场景:
当打开一个文件并希望在调用exec
函数(如 execl
, execv
等)时,不希望新进程继承该文件描述符时,可以使用 O_CLOEXEC
。这在处理临时文件或需要限制访问的文件时特别有用。
那么此处选择了一个 通过上述漏洞分析,最终可以引出新的标志位 本文通过分析四个与文件操作相关的API函数所导致的漏洞,发现开发过程中对符号链接的忽视,可以逐渐演变成各种各样的安全问题,包括隐私绕过和系统提权。 在代码设计过程中,如果对suid
属性的系统root用户可执行文件crontab
,因为带有suid
属性的可执行文件可以以对应文件所属用户的权限进行执行:crontab
是系统中用于设置周期性被执行指令的命令,通过crontab -e
命令可以执行随之所给定的编辑器。当crontab
执行所给定的文件编辑器的时候,则会将文件描述符暴露给攻击者,通过所暴露的文件描述符则可向特定的文件写入数据。O_NOFOLLOW_ANY
,和renameatx_np
函数的RENAME_NOFOLLOW_ANY
字段类似,它将限制整个路径存在符号链接的可能性,能最大限制的杜绝由符号链接导致操作文件行为的劫持。O_NOFOLLOW
等字段的使用不当或考虑不周全,仍然可能被绕过;或者没有禁止O_CLOEXEC
字段,可能导致原本较小的漏洞扩大影响,从任意目录写文件演变成稳定的本地权限提升。无论是Linux、macOS还是Windows,近年来都存在多个由于符号链接导致的严重漏洞。这些逻辑漏洞的稳定性和可利用性都非常高,是一个不可忽视的安全方面。
1. CVE-2020-9900 & CVE-2021-1786 - Abusing macOS Crash Reporter
2. badmalloc (CVE-2023-32428) - a macOS LPE
3. lateralus (CVE-2023-32407) - a macOS TCC bypass
【版权说明】 本作品著作权归fmyy所有 未经作者同意,不得转载 fmyy 天工实验室安全研究员 专注于macOS安全、IoT安全
自定义模型:
{文章来源和文章摘要}
奇安信天工实验室公众号发布的文章《系统文件管理行为漏洞导致本地提权》详细分析了符号链接在本地提权中的利用,特别是通过OPEN和RENAME等函数的行为漏洞,探讨了如何在不同操作系统中利用这些漏洞进行攻击,并提出了相应的防护措施。
======
{文章总结}
文章指出,符号链接在本地提权中的利用日益增多,尤其是在macOS、Windows和Linux等操作系统中。通过分析OPEN和RENAME等函数的漏洞,攻击者可以利用这些漏洞进行文件操作劫持,从而实现本地提权。文章还介绍了如何通过监控系统行为和设置断点来检测和分析这些漏洞,并提出了改进建议,如引入新的标志位O_NOFOLLOW_ANY来限制符号链接的使用,以防止操作文件行为的劫持。
======
{对文章的看法}
这篇文章深入剖析了符号链接在本地提权中的利用,提供了详细的漏洞分析和防护建议,具有很高的技术价值。文章不仅指出了当前系统文件管理中的安全隐患,还提出了切实可行的改进措施,对于提升系统安全性具有重要意义。同时,文章结构清晰,逻辑严谨,适合安全研究人员和系统开发者阅读和参考。
微信扫一扫
关注该公众号