tuned: D-Bus方法instance_create中的本地root漏洞及tuned >= 2.23中的其他问题 (CVE-2024-52336, CVE-2024-52337)
#CVE #local #D-Bus目录
1) 引言
Tuned是一个用于Linux的特权守护进程,支持在运行时自动调整各种硬件和内核设置。该守护进程提供了一个受Polkit认证保护的全面D-Bus接口。我们会定期审查新引入的D-Bus系统服务及其更改。Tuned的D-Bus接口经常有新增功能,这是我们自2019年以来进行的第十次审查。通常审查都比较直接,我们也没有什么抱怨,但这次是个例外。
在审查过程中,我们检查了匹配以下Polkit操作的D-Bus方法
com.redhat.tuned.instance_create (auth_admin:auth_admin:yes)
com.redhat.tuned.instance_destroy (auth_admin:auth_admin:yes)
net.hadess.PowerProfiles.HoldProfile (no:no:yes)
net.hadess.PowerProfiles.ReleaseProfile (no:no:yes)
本报告基于tuned版本v2.24.0。
2) D-Bus方法instance_create中的问题
调用instance_create() D-Bus方法允许本地登录用户在无身份验证的情况下调用(Polkit设置为yes)。该方法调用接受包括options字典在内的各种参数,这些参数完全由攻击者控制。
2a) 脚本选项允许本地root漏洞 (CVE-2024-52336)
script_pre和script_post选项允许传递任意脚本,这些脚本将由*root*执行。参数在daemon/controller.py:459处提取,未修改地存储在新的Instance对象中,并且仅在plugins/base.py:222中执行脚本路径的唯一验证。
if not script.startswith("/"):
log.error("Relative paths cannot be used in script_pre or script_post. " \
+ "Use ${i:PROFILE_DIR}.")
return False
因此,唯一的要求是传递一个绝对路径。这样,非特权用户控制下的脚本就可以被传递。这使得本地root漏洞成为可能。
重现步骤
以本地登录的非特权用户身份执行以下D-Bus调用
$ gdbus call -y -d com.redhat.tuned -o /Tuned \
-m com.redhat.tuned.control.instance_create cpu myinstance \
'{"script_pre": "/path/to/myscript.sh", "devices": "*"}'
路径/path/to/myscript.sh需要替换为用户控制的可执行脚本或程序的路径。它将由tuned以root权限执行。
2b) 实例名称可以包含任意数据 (CVE-2024-52337)
instance_create()方法的instance_name参数未被净化。此字符串稍后用于日志记录以及tuned-adm get_instances等实用程序的输出,或使用tuned的D-Bus接口获取实例名称的其他第三方程序。
本地攻击者可以在实例名称中包含任意数据,从而实现日志伪造。通过在名称中放置换行符,可以向tuned日志添加看似独立、合法的条目。通过添加终端控制序列,可以影响管理员或其他用户的终端模拟器。以下是此漏洞的概念验证:
$ EVIL=`echo -e "this is\nevil\033[?1047h"`
$ gdbus call -y -d com.redhat.tuned -o /Tuned -m com.redhat.tuned.control.instance_create cpu "$EVIL" '{"devices": "*"}'
当另一个用户调用tuned-adm get_instances时,终端模拟器在输出经过精心制作的实例名称时会切换到备用屏幕。
受影响情况
instance_create() D-Bus方法已通过上游提交cddcd233添加,并首次包含在v2.23.0版本标签中。初始版本已经支持脚本选项参数和instance_name参数。
3) PowerProfiles接口中的问题
3a) PowerProfiles API中的Cookie可预测
新的D-Bus方法HoldProfile()和ReleaseProfile()使用一个cookie来标识配置的保持。cookie只是一个从零开始连续递增的整数。这意味着系统中的其他用户可以轻松释放其他用户的配置保持。
3b) 用户提供的字符串可能包含任意数据
HoldProfile()调用接受reason和app_id字符串,这些字符串用于日志记录,并可能通过ProfileHold.as_dict()作为字典返回。这些字符串可能再次包含精心制作的数据,这些数据可能产生与第2b节所示类似的副作用。
建议的修复方案
使用cookie的本地DoS场景仅在多用户系统上,或者当Polkit设置放宽,使得非本地会话也能使用这些D-Bus方法时才是一个问题。一种使其更健壮的方法可能是发出随机的cookie ID,以使攻击不那么容易。
4) Bug修复
上游发布了版本v2.24.1,解决了本报告中描述的问题。提交90c24eea037包含累积修复,如下所示:
- 插件现在只从受信任的位置加载(
_safe_script_path()函数)。 - 如果用户提供的字符串包含不允许的字符,则会拒绝这些字符串(
is_valid_name()函数)。 - 上游还收紧了
instance_create及其他一些他们也认为存在问题的、由本地非特权用户访问的操作的tuned Polkit策略。
对于问题3a),目前没有上游修复。这更多的是一个加固建议。
5) 时间线
| 2024-11-07 | 我们已将这些问题报告给Red Hat安全团队。 |
| 2024-11-08 | Red Hat安全团队确认了这些问题,并向我们传达了CVE分配情况,并建议发布日期为2024年11月26日。 |
| 2024-11-11 | Red Hat分享了建议的补丁,我们对其进行了审查。 |
| 2024-11-26 | 发布日期已到,并按计划进行了发布。 |