ncurses-overflow.txt

2000-10-11T00:00:00
ID PACKETSTORM:23295
Type packetstorm
Reporter Jouko Pynnonen
Modified 2000-10-11T00:00:00

Description

                                        
                                            `OVERVIEW  
  
The CRT screen handling library ncurses contains buffer overflows,  
making programs using it vulnerable. If the programs are setuid or  
setgid, a local user may elevate their privilege. The problem exists in  
ncurses versions 4.2 and 5.0, probably earlier, and libocurses. The  
overflows can be exploited if the library implementation supports  
loading of user defined terminfo files from ~/.terminfo.  
  
The problem has been tested and found on  
  
* SuSE Linux 6.4, Red Hat Linux 6.1. A setuid program using ncurses  
("cda" in the xmcd package) was successfully exploited to spawn a  
root shell.  
  
* FreeBSD, the program /usr/bin/systat is setgid and uses libncurses.  
An exploit was made which gives a shell with egid=3Dkmem. The kmem  
group has read access to /dev/kmem and memory of all processes via  
/proc/<pid>/mem, and could be used to read e.g. crypted or  
cleartext passwords, authorization keys, or any other info that  
might be in programs' memory space.  
  
* OpenBSD, having /usr/bin/systat setgid kmem too. No test exploit  
was made, but the program segfaults when given an "evil" terminfo  
file. Making a similar exploit is probably possible. This applies to  
other BSD systems as well, but haven't been tested or confirmed.  
  
All programs using ncurses aren't necessarily vulnerable, e.g. "screen"  
is setuid root on some systems and uses ncurses, but it doesn't seem to  
use the vulnerable functions at least directly (investigated on Red Hat  
Linux, other systems may vary).  
  
When using telnet to connect to a remote system, telnetd on some  
platforms doesn't ignore TERMINFO_DIRS or TERMCAP environment variables  
(e.g. OpenBSD). This means the problem could be remotely exploitable  
under some conditions on some platforms. This hasn't been confirmed with  
an exploit, however by setting TERMCAP the OpenBSD telnetd can be made  
read any file as root. If the file is something like /dev/zero, the  
telnetd process reads it infinitely until the system runs out of memory.  
  
  
  
BUG DETAILS  
  
The file ncurses/tty/lib_mvcur.c contains functions for moving around  
the cursor. Some of the functions contain calls to strcpy() without  
bound checking. The target of the strcpy's is a local fixed size buffer  
in onscreen_mvcur():  
  
static inline int  
onscreen_mvcur(int yold,int xold,int ynew,int xnew, bool ovw)  
/* onscreen move from (yold, xold) to (ynew, xnew) */  
{  
char use[OPT_SIZE], *sp;  
  
  
=2E.. a few lines later:  
  
sp =3D tparm(SP->_address_cursor, ynew, xnew);  
if (sp)  
{  
tactic =3D 0;  
(void) strcpy(use, sp);  
  
  
The function tparm() returns a control string for screen manipulation,  
originating from the terminfo file read according to the environment  
variables TERM and TERMINFO_DIRS. Even though ncurses implementations  
on some platforms reportedly ignore TERMINFO_DIRS while running  
setuid/setgid, they check ~/.terminfo/ for the capability files in any  
case.  
  
OPT_SIZE seems to be defined as 512. tparm() can be made return a  
string of arbitrary length containing arbitrary data, so exploitation is  
usually quite trivial. There are a few of similar strcpy() calls in  
other functions in the file. Many other ncurses functions may also call  
the cursor moving functions (e.g. endwin()) so in order to be  
vulnerable, a program needn't call mvcur().  
  
  
  
SOLUTION  
  
The authors of ncurses and OS vendors have been informed over a week  
ago and they have, or will release fix packages shortly.  
  
  
  
TEMPORARY WORKAROUND  
  
A temporary solution is to remove the setuid/setgid bits of programs  
using ncurses. To check if a program uses ncurses, type (on most  
systems):  
  
ldd /path/to/program  
  
If libncurses or libocurses is mentioned in the library listing and the  
program is setuid/setgid, then there's a possibility for it to be  
exploited. If 'ldd' doesn't exist on the system (or the program is  
statically linked) you can try something like  
  
grep -li TERMINFO /path/to/program  
  
If it outputs the file path, the program probably uses ncurses or  
derivative.  
  
To remove the setuid/setgid bits, issue the command:  
  
chmod ug-s /path/to/file  
  
  
  
CREDITS AND ACKNOWLEDGEMENTS  
  
Vulnerability discovered by: Jouko Pynn=F6nen <jouko@solutions.fi>  
  
Thanks and greets to: Emil Valsson (for providing a FreeBSD test box),  
Esa Etel=E4vuori, ncurses people, cc-opers@IRCNet  
  
  
  
--  
Jouko Pynn=F6nen Online Solutions Ltd Secure your Linux -  
jouko@solutions.fi http://www.secmod.com  
  
`