Title: Stack-based buffer overflow in CDE libDtSvc
Application: Common Desktop Environment 2.3.1 and earlier
Common Desktop Environment 1.6 and
earlier2020-06-cde-libDtSvc.txt
Platforms: Oracle Solaris 10 1/13 (Update 11) and earlier
Other platforms are potentially affected (see below)
Description: A difficult to exploit stack-based buffer overflow in
the
libDtSvc library distributed with CDE may allow local users to
corrupt memory and potentially execute aritrary code in order
to escalate privileges
Author: Marco Ivaldi <
Vendor Status: Oracle <
CERT/CC notified on 2019-12-15 (tracking VU#308289)
CVE Name: CVE-2020-2851
CVSS Vector: CVSS:3.0/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:H/A:H (Base
Score: 7.8)
References:
https://github.com/0xdea/advisories/blob/master/2020-06-cde-libDtSvc.txt
https://www.oracle.com/security-alerts/cpuapr2020.html
https://sourceforge.net/p/cdesktopenv/wiki/Home/
https://www.oracle.com/technetwork/server-storage/solaris10/
https://www.mediaservice.net/
https://0xdeadbeef.info/
1. Abstract.
A difficult to exploit stack-based buffer overflow in the
_DtCreateDtDirs()
function in the Common Desktop Environment version distributed with
Oracle
Solaris 10 1/13 (Update 11) and earlier may allow local users to
corrupt memory
and potentially execute arbitrary code in order to escalate
privileges via a
long X11 display name. The vulnerable function is located in the
libDtSvc
library and can be reached by executing the setuid program
dtsession.
Note that Oracle Solaris CDE is based on the original CDE 1.x
train, which is
different from the CDE 2.x codebase that was later open sourced. In
detail, the
open source CDE is not affected by this specific vulnerability, but
following
our report some additional work has been done by its maintainers to
properly
check bounds in the libDtSvc library. Most notably, insecure calls
to strncat()
that caused buffer overflows have been fixed.
2. Example Attack Session.
In order to reproduce this bug, the following commands can be used:
bash-3.2$ cat /etc/release
Oracle Solaris 10 1/13 s10x_u11wos_24a X86
Copyright (c) 1983, 2013, Oracle and/or its affiliates. All rights
reserved.
Assembled 17 January 2013
bash-3.2$ uname -a
SunOS nostalgia 5.10 Generic_147148-26 i86pc i386 i86pc
bash-3.2$ id
uid=54322(raptor) gid=1(other)
bash-3.2$ grep 10.0.0.24 /etc/hosts
10.0.0.24
aaaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
[activate a valid display on 10.0.0.24:0]
/usr/dt/bin/dtsession -display
aaaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:0
Segmentation Fault
3. Discussion.
The overflow occurs in the following code snippet of Oracle
Solaris CDE (the
Ghidra decompiler is probably doing something wrong as some
variables seem to
overlap, however its output is good enough for the purpose of this
discussion):
char * _DtCreateDtDirs(int param_1)
{
...
char local_f0 [104];
char local_88 [112];
char *heap_path2;
char *tmp_ptr1;
char *home;
undefined *local_c;
undefined local_8 [4];
...
if (param_1 != 0) {
strcpy(local_f0,*(char **)(param_1 + 0x80));
strcpy(local_88,*(char **)(param_1 + 0x80));
...
}
An X11 display data structure is passed to the _DtCreateDtDirs()
function as
its only parameter (param_1 in the pseudocode above). It contains
the X11
display name at offset 0x80. This display name is copied into the
stack buffers
local_f0 and local_88 using the insecure function strcpy() twice,
therefore two
overflows occur.
Based on the inferred stack layout, the following local
variables are
overflowed into before the saved return address can be reached:
heap_path2
tmp_ptr1
home
local_c
local_8
This complicates exploitation, in particular because the
heap_path2 and
tmp_ptr1 pointers get in the way. A skilled attacker might be able
to overwrite
all variables with safe data and leverage memory corruption to
obtain arbitrary
code execution. However, there is an additional challenge: the
ability to
control a hostname to be passed in the X11 display name string. In
our PoC
above we have edited /etc/hosts, but this is obviously not possible
for an
unprivileged local attacker. A DNS server under the control of the
attacker may
be used for this purpose, but such an approach would introduce a
number of
additional complications.
That said, as a rule of thumb all memory corruption issues have
the potential
to become serious security vulnerabilities until otherwise proven.
Therefore,
we recommend to treat this bug as a potential security
vulnerability and to fix
it as such.
4. Affected Platforms.
All platforms shipping the Common Desktop Environment are
potentially affected.
This includes:
* Oracle Solaris 10 1/13 (Update 11) and earlier [default installation]
According to the CDE Wiki, the following platforms are officially supported:
* All Official Ubuntu variants 12.04 - 18.04
* Debian 6, 7, 8, 9
* Fedora 17 at least
* Archlinux
* Red Hat
* Slackware 14.0
* OpenBSD
* NetBSD
* FreeBSD 9.2, 10.x, 11.x
* openSUSE Tumbleweed (gcc7)
* openSUSE Leap 4.2 (gcc4)
* SUSE 12 SP3 (gcc4)
* Solaris, OpenIndiana
5. Fix.
The maintainers of the open source CDE 2.x version have issued
the following
patches:
https://sourceforge.net/p/cdesktopenv/mailman/message/36900154/
https://sourceforge.net/p/cdesktopenv/code/ci/6b32246d06ab16fd7897dc344db69d0957f3ae08/
Oracle, which maintains a different CDE codebase based on the
1.x train, has
assigned the tracking# S1240932 and has released a fix for all
affected and
supported versions of Solaris in the Critical Patch Update (CPU) of
April 2020.
As a workaround, it is also possible to remove the setuid bit
from the
vulnerable executable as follows (note that this might prevent it
from working
properly):
bash-3.2# chmod -s /usr/dt/bin/dtsession
Please note that during the audit many other potentially
exploitable bugs have
surfaced in libDtSvc and in the Common Desktop Environment in
general.
Therefore, removing the setuid bit from all CDE binaries is
recommended,
regardless of patches released by vendors.
Copyright (c) 2020 Marco Ivaldi and @Mediaservice.net. All
rights reserved.

