Arbitrary code execution breaking sandboxes in KDE Plasma
Arbitrary code execution breaking sandboxes in KDE Plasma
KDE Plasma 中的任意代码执行漏洞:沙盒逃逸分析
PoC
This proof of concept demonstrates a mean for malicious sandboxed (Flatpak here, but any sandbox apply. With or without the security context support.) applications to impersonate and, more importantly, spawn arbitrary binaries on the host when user invokes Open New Window action. This demonstration utilises Arch Linux host with some dependencies (wget, unzip, meson) to build the malicious binary, and a Flatpak application io.github.johannesboehler2.BmiCalculator with no granted permission (except for the evil binary we have to pass in, because building things inside Flatpak is not easy). You will need kcalc (/usr/bin/kcalc) as the designated target.
概念验证 (PoC)
此概念验证展示了一种恶意沙盒应用(此处以 Flatpak 为例,但适用于任何沙盒,无论是否支持安全上下文)在用户触发“打开新窗口”操作时,冒充并(更重要的是)在宿主机上生成任意二进制文件的方法。该演示使用 Arch Linux 宿主机,并安装了一些依赖项(wget, unzip, meson)来构建恶意二进制文件,同时使用了一个未授予任何权限的 Flatpak 应用 io.github.johannesboehler2.BmiCalculator(除了我们需要传入的恶意二进制文件,因为在 Flatpak 内部构建程序并不容易)。你需要将 kcalc (/usr/bin/kcalc) 作为指定目标。
Build the evil binary on host: 在宿主机上构建恶意二进制文件:
cd /tmp
wget https://github.com/Kimiblock/mesa-demos-argv0/archive/refs/heads/argv0.zip
unzip argv0.zip
cd mesa-demos-argv0-argv0
meson setup build
meson compile -C build/
Install the Flatpak app and provide said binary to it. 安装 Flatpak 应用并将上述二进制文件提供给它。
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install -y io.github.johannesboehler2.BmiCalculator --user
flatpak override io.github.johannesboehler2.BmiCalculator --filesystem=/tmp/mesa-demos-argv0-argv0/build/src/egl/opengl/eglgears_wayland
Now that it’s all set, let’s run the evil binary: 现在一切准备就绪,让我们运行恶意二进制文件:
flatpak run --command=/tmp/mesa-demos-argv0-argv0/build/src/egl/opengl/eglgears_wayland io.github.johannesboehler2.BmiCalculator
Notice that in the task bar, KCalc‘s icon is being shown. If we right click and select Open New Window, the designated binary /usr/bin/kcalc starts unsandboxed, in the app.slice cgroup, using the host mount namespace, fully exposed.
请注意,任务栏中显示了 KCalc 的图标。如果我们右键点击并选择“打开新窗口”,指定的二进制文件 /usr/bin/kcalc 将在未沙盒化的状态下启动,位于 app.slice cgroup 中,使用宿主机的挂载命名空间,完全暴露。
Discovery
While testing the Portable sandbox on KDE Plasma (in a QEMU virtual machine), we just casually found out some of the windows does not have proper .desktop file associated, leaving them show up in task bar with generic “Wayland” icons. That was reported in KWin trusts on Apps fully for app_id, allowing apps to impersonate as others.
发现
在 KDE Plasma 上(通过 QEMU 虚拟机)测试 Portable 沙盒时,我们偶然发现一些窗口没有关联正确的 .desktop 文件,导致它们在任务栏中显示为通用的“Wayland”图标。这一问题已在“KWin 完全信任应用的 app_id,允许应用冒充其他应用”的报告中提及。
Something hits the fan
Since then, we had no indication on how things work on this specific desktop environment. So I decided to conduct another experiment. This time a new anomaly popped up: While accidently middle clicking on the task bar (it would invoke “Open New Window” by default for a specific app), the app launched a new window as expected, yet it did not seem to remember my saved login credentials, nor did it use any of modified settings. Upon closer inspection, combining the PID obtained from KWin Debug Console and control groups + rootfs info from procfs, a complete sandbox escape has surfaced.
状况恶化
此后,我们对该特定桌面环境的工作机制缺乏了解。因此,我决定进行另一次实验。这次出现了一个新的异常:在任务栏上意外点击鼠标中键(默认会为特定应用调用“打开新窗口”)时,应用按预期启动了一个新窗口,但它似乎没有记住我保存的登录凭据,也没有使用任何修改后的设置。经过仔细检查,结合从 KWin 调试控制台获取的 PID 以及 procfs 中的控制组和根文件系统信息,一个完整的沙盒逃逸漏洞浮出水面。
Explaination
So it was clear, there is a complete sandbox escape when I accidently triggered a middle-click inside the virtual machine. What’s it doing? Based on the fact that KWin could not associate the window to a real .desktop file, there must be something that still allows it to find a argv0 to execute. I took a guess on /proc/PID/cmdline and it proved to be right. See the demo below.
解释
很明显,当我在虚拟机中意外触发鼠标中键时,发生了完整的沙盒逃逸。它是如何运作的?基于 KWin 无法将窗口关联到真实的 .desktop 文件这一事实,必然存在某种机制允许它找到要执行的 argv0。我猜测是 /proc/PID/cmdline,事实证明确实如此。请参阅下方的演示。
It’s a dumpster fire
This is not limited to spawning existing application instances outside of the sandbox. Since it just so happens that any process, including unprivileged ones can change it’s argv0 (Note that mount namespace is also a valid choice, but less flexible.). Combined with the lack of guard on app_id, the insecure nature of reading /proc/PID/cmdline, creates a powerful exploit that allows arbitrary code execution on the host.
一团糟
这不仅限于在沙盒外生成现有的应用实例。由于任何进程(包括无特权进程)都可以更改其 argv0(注意挂载命名空间也是一种有效选择,但灵活性较低),再加上对 app_id 缺乏防护,以及读取 /proc/PID/cmdline 的不安全性,共同构成了一个强大的漏洞,允许在宿主机上执行任意代码。
Demo time
This demo is written by GalaxySnail since I had little knowledge in C. We will be using Mesa’s eglgears-wayland as a demo.
Clone the repository: git clone https://github.com/Kimiblock/mesa-demos-argv0.git --depth=1
Change working directory: cd mesa-demos-argv0/
Edit the designated command within the main function at src/egl/opengl/eglgears.c to your liking (bash scripts, compiled binaries, you name it)
Build: meson setup build && meson compile -C build
Execute the payload: ./build/src/egl/opengl/eglgears_wayland
Open New Window (either middle-click on the icon, or select it in the context menu)
Our designated evil binary starts up
演示时间
由于我对 C 语言知之甚少,此演示由 GalaxySnail 编写。我们将使用 Mesa 的 eglgears-wayland 作为演示。
克隆仓库:git clone https://github.com/Kimiblock/mesa-demos-argv0.git --depth=1
更改工作目录:cd mesa-demos-argv0/
根据你的喜好编辑 src/egl/opengl/eglgears.c 中 main 函数内的指定命令(bash 脚本、编译后的二进制文件等)
构建:meson setup build && meson compile -C build
执行载荷:./build/src/egl/opengl/eglgears_wayland
打开新窗口(点击图标中键,或在上下文菜单中选择)
我们指定的恶意二进制文件启动了。
Cool, now what?
A real attack will probably generate a shell script under their $HOME, of which typically resides on the host with the same path. The evil app can change it’s argv0 to point at binaries generated or downloaded silently, and have total control of the session when the user clicks Open New Window, or just middle-clicks the application icon by mistake. This demonstrates a powerful attack, yet we did not receive any updates from the KDE Security email. If KDE Plasma wants to plug this exploit in any capacity, then it should first get the applications’ ID from either the sandbox via security context / XdpAppInfo or control groups and do not trust application provided ID. It also need to stop allowing “Open New Window” when there is not a match for that specific window with a .desktop file.
酷,然后呢?
真正的攻击可能会在用户的 $HOME 下生成一个 shell 脚本,该路径通常与宿主机上的路径相同。恶意应用可以将其 argv0 指向静默生成或下载的二进制文件,并在用户点击“打开新窗口”或仅仅是误点击应用图标时,完全控制会话。这展示了一种强大的攻击方式,但我们没有收到来自 KDE 安全邮箱的任何更新。如果 KDE Plasma 想要以任何方式修补此漏洞,首先应该通过安全上下文/XdpAppInfo 或控制组从沙盒获取应用 ID,而不是信任应用提供的 ID。此外,当特定窗口没有匹配的 .desktop 文件时,也应禁止“打开新窗口”功能。
Timeline
Note that in the original mail, I mistakenly spelled arbitrary code execution as RCE. All events are listed using UTC +8 time zone, using 24h time format.
时间线
请注意,在最初的邮件中,我错误地将“任意代码执行”拼写为 RCE。所有事件均使用 UTC +8 时区和 24 小时制时间格式列出。
| Time | Event |
|---|---|
| April 1 2026, 23:51 | The first email was sent to security@kde.org |
| April 2 2026, 00:15 | David Edmundson david@davidedmundson.co.uk replies to the mail acknowledging the report |
| April 2 2026, 00:24 | David Edmundson david@davidedmundson.co.uk said the function “uses the Exec= from that desktop file” and they “don’t think it can be used to run arbitrary code” |
| April 2 2026, 11:59 | I got another PoC working with the help of GalaxySnail, confirming that it does not depend on a any .desktop file |
| April 2 2026, 18:26 | A follow up mail was sent to security@kde.org, with an exploit file and an explanation. But got no response. |
| May 2 2026, 11:59 | A check was performed with Plasma 6.7 Beta, showing the exploit was not patched. |
| July 2 2026, 18:30 | The exploit has exceeded a waiting period of 90 days whilst still active, so we proceed to publication. |
| 时间 | 事件 |
|---|---|
| 2026年4月1日 23:51 | 第一封邮件发送至 security@kde.org |
| 2026年4月2日 00:15 | David Edmundson (david@davidedmundson.co.uk) 回复邮件确认收到报告 |
| 2026年4月2日 00:24 | David Edmundson 表示该功能“使用了来自 desktop 文件的 Exec=”,他们“认为它不能被用于运行任意代码” |
| 2026年4月2日 11:59 | 在 GalaxySnail 的帮助下,我完成了另一个 PoC,证实它不依赖于任何 .desktop 文件 |
| 2026年4月2日 18:26 | 发送了后续邮件至 security@kde.org,附带了漏洞利用文件和解释,但未收到回复。 |
| 2026年5月2日 11:59 | 使用 Plasma 6.7 Beta 进行检查,显示该漏洞未被修补。 |
| 2026年7月2日 18:30 | 该漏洞已超过 90 天的等待期且仍然有效,因此我们进行公开披露。 |
Because the exploit went un-patched and no follow up reply was received, combined with a typical 90-day wait, we… 由于该漏洞未被修补且未收到后续回复,结合通常的 90 天等待期,我们……