Bug 1213708 (CVE-2023-32184) - VUL-0: CVE-2023-32184: opensuse-welcome: local arbitrary code execution in XFCE environment if custom desktop layout is selected
Summary: VUL-0: CVE-2023-32184: opensuse-welcome: local arbitrary code execution in XF...
Status: RESOLVED FIXED
Alias: CVE-2023-32184
Product: SUSE Security Incidents
Classification: Novell Products
Component: Incidents (show other bugs)
Version: unspecified
Hardware: Other Other
: P3 - Medium : Normal
Target Milestone: ---
Assignee: Matthias Gerstner
QA Contact: Security Team bot
URL: [none]
Whiteboard: CVSSv3.1:SUSE:CVE-2023-32184:7.8:(AV:...
Keywords:
Depends on:
Blocks: 1213340
  Show dependency treegraph
 
Reported: 2023-07-27 09:29 UTC by Matthias Gerstner
Modified: 2023-09-20 03:16 UTC (History)
4 users (show)

See Also:
Found By: ---
Services Priority:
Business Priority:
Blocker: ---
Marketing QA Status: ---
IT Deployment: ---


Attachments
PoC program (5.36 KB, text/x-script.python)
2023-07-27 09:34 UTC, Matthias Gerstner
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Gerstner 2023-07-27 09:29:51 UTC
+++ This bug was initially created as a clone of Bug #1213340

The opensuse-welcome dialog is a small Qt program containing not even 500
lines of code. It uses some advanced Qt features like QML scripts, though,
which help in setting up the dialog's features.

One peculiarity is that only in an XFCE environment (`$XDG_CURRENT_DESKTOP`
set to xfce), a "customise" button is shown which allows to select between
different XFCE desktop layout presets.

Understanding the setup of this XFCE specific customise button is not all that
simple. There are QML tag attributes "data-de" which relate to specific
desktop environments. There is a XfceLayouter registered in QML and in
src/main.cpp.

In any case the C++ class found in panellayouter.h and panellayouter.cpp is
dealing with the actual logic that is executed once the user clicks on any of
the XFCE desktop layout presets, to configure it.

In `PanelLayouter::applyLayout()` the fixed path /tmp/layout is used to store
a complex configuration file which is fed to the XFCE via D-Bus. To complicate
things further, a Python script embedded into panellayouter.cpp is used to
take advantage of the XFCE4 Python module found in
/usr/share/xfce4-panel-profiles/xfce4-panel-profiles/panelconfig.py. This
module offers facilities to feed a desktop layout configuration tarball to
XFCE via D-Bus.

The use of the fixed path in /tmp/layout is problematic security wise in
multiple ways. The following code is used in `PanelLayouter::applyLayout()`:

```
    if (QFile::exists("/tmp/layout"))
        QFile::remove("/tmp/layout");

    QFile layout(path);
    layout.copy("/tmp/layout");

    QProcess::startDetached("/usr/bin/python3", {"-c", m_script});
```

This results in the following system call sequence, provided /tmp/layout does
not yet exist:

```
access("/tmp/layout", F_OK)             = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/tmp", O_RDWR|O_CLOEXEC|O_TMPFILE, 0600) = 55
linkat(AT_FDCWD, "/proc/self/fd/55", AT_FDCWD, "/tmp/layout", AT_SYMLINK_FOLLOW)
= 0
chmod("/tmp/layout", 0444)              = 0
```

This of course poses various attack vectors involving symlink attacks. If the
Linux kernel's symlink protection is off, other users can place symlinks here
to confuse the existence check or to overwrite arbitrary locations (the
`linkat()` call explicitly specifies `AT_SYMLINK_FOLLOW`). By default on
openSUSE we do have symlink protection, luckily.

What happens if /tmp/layout already exists as a regular file, though? The code
above does not perform any error checks and C++ exceptions are not used
either. This means a failing `Qfile::remove()` or a failing `QFile.copy()` are
not noticed and are not terminating the program logic. The result of this will
be, if /tmp/layout is already existing and readable, that attacker controlled
data is used in the embedded Python script.

When looking at the logic found in /usr/share/xfce4-panel-profiles/xfce4-panel-profiles/panelconfig.py
we can see that a tarball is expected as input containing complex
configuration files. Among other the script copies any `*.rc` files found in
the tarball into the user's home directory. The script does have quite some
evaluation logic, but it is sloppy enough to allow to construct a crafted
tarball that causes an arbitrary file in the user's home directory to be
overwritten by attacker controlled data.

The attached `hack_welcome.py` script is a PoC I wrote that demonstrates this.
The impact is arbitrary code execution in the context of the victim user that
runs XFCE and clicks customize in opensuse-welcome and chooses one of the
layouts. Currently the only limitation is that the name of the victim's user
account needs to be known. I suspect there are further attack vectors to make
this even simpler. Refer to the PoC inline documentation for more.
Comment 1 Matthias Gerstner 2023-07-27 09:34:32 UTC
Created attachment 868450 [details]
PoC program
Comment 4 Johannes Segitz 2023-07-28 09:59:25 UTC
Please use CVE-2023-32184 for this
Comment 5 Matthias Gerstner 2023-07-31 11:34:43 UTC
There are only openSUSE community maintainers for this package and even them
don't seem to be much involved into the package. I will attempt a fix myself,
shouldn't be too hard.

Doing this privately will be difficult, I guess I will communicate openly that
there is a CVE fixed by this, but not publish this bug here with the details
before updates are available.
Comment 6 Matthias Gerstner 2023-08-01 11:37:35 UTC
I just create the GitHub PR# to address this:

https://github.com/openSUSE/openSUSE-welcome/pull/32

Turns out this is even weirder than what it looked like at first. I thought
the layout tarballs are actually coming from the xfce4-panel-profiles package,
installed in /usr/share/xfce4-panel-profiles/layouts.

Instead a couple of layout tarballs are embedded into opensuse-welcome as
"application resources". This is probably also the reason why this stunt with
the /tmp/layout fixed path was introduced in the first place. It was used as a
vehicle to write the embedded tarballs to disk. The Qt libraries transparently
handle special paths starting with a colon as application resource paths.

In my PR# I am now using a QTemporaryFile to write out the application
resource. The embedded Python script is now an external file that needs to be
packaged. This should make things clearer and more importantly fix the
security issue.
Comment 8 Johannes Segitz 2023-08-11 13:47:01 UTC
submitted in https://build.opensuse.org/request/show/1103483, removing embargoed tag, but I'll leave the bug private for now
Comment 9 OBSbugzilla Bot 2023-08-11 14:25:02 UTC
This is an autogenerated message for OBS integration:
This bug (1213708) was mentioned in
https://build.opensuse.org/request/show/1103493 Factory / opensuse-welcome
https://build.opensuse.org/request/show/1103495 Backports:SLE-15-SP5 / opensuse-welcome
Comment 10 OBSbugzilla Bot 2023-08-14 09:35:04 UTC
This is an autogenerated message for OBS integration:
This bug (1213708) was mentioned in
https://build.opensuse.org/request/show/1103813 Backports:SLE-15-SP5 / opensuse-welcome
https://build.opensuse.org/request/show/1103814 Backports:SLE-15-SP4 / opensuse-welcome
Comment 11 Marcus Meissner 2023-08-14 19:05:34 UTC
openSUSE-SU-2023:0219-1: An update that fixes one vulnerability is now available.

Category: security (important)
Bug References: 1213708
CVE References: CVE-2023-32184
JIRA References: 
Sources used:
openSUSE Backports SLE-15-SP5 (src):    opensuse-welcome-0.1.9+git.35.4b9444a-bp155.2.3.1
Comment 12 Marcus Meissner 2023-08-18 13:05:32 UTC
openSUSE-SU-2023:0230-1: An update that fixes one vulnerability is now available.

Category: security (moderate)
Bug References: 1213708
CVE References: CVE-2023-32184
JIRA References: 
Sources used:
openSUSE Backports SLE-15-SP4 (src):    opensuse-welcome-0.1.9+git.0.66be0d8-bp154.2.6.1
Comment 13 Matthias Gerstner 2023-08-21 10:06:37 UTC
Updates are now in place for all maintained openSUSE codestream. Publishing
and closing this bug.